- input data rate can be lower than filter
git-svn-id: http://moon:8086/svn/vhdl/trunk@198 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -16,4 +16,4 @@ do {tb_fir_semi_parallel.wdo}
|
|||||||
view wave
|
view wave
|
||||||
view structure
|
view structure
|
||||||
view signals
|
view signals
|
||||||
run 400us
|
run 120us
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/clk
|
|||||||
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/h_addr
|
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/h_addr
|
||||||
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/h_we
|
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/h_we
|
||||||
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/h_in
|
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/h_in
|
||||||
add wave -noupdate -format Logic /tb_fir_semi_parallel/din_vld
|
|
||||||
add wave -noupdate -format Logic /tb_fir_semi_parallel/dout_vld
|
add wave -noupdate -format Logic /tb_fir_semi_parallel/dout_vld
|
||||||
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/d_in
|
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/d_in
|
||||||
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/d_out
|
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/d_out
|
||||||
@@ -14,7 +13,11 @@ add wave -noupdate -divider {Real out}
|
|||||||
add wave -noupdate -format Analog-Step -height 50 -scale 50.0 /tb_fir_semi_parallel/xi
|
add wave -noupdate -format Analog-Step -height 50 -scale 50.0 /tb_fir_semi_parallel/xi
|
||||||
add wave -noupdate -format Analog-Step -height 50 -scale 50.0 /tb_fir_semi_parallel/yo
|
add wave -noupdate -format Analog-Step -height 50 -scale 50.0 /tb_fir_semi_parallel/yo
|
||||||
add wave -noupdate -divider -height 50 <NULL>
|
add wave -noupdate -divider -height 50 <NULL>
|
||||||
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/count_array
|
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/en
|
||||||
|
add wave -noupdate -format Logic /tb_fir_semi_parallel/uut/ce0
|
||||||
|
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/count0
|
||||||
|
add wave -noupdate -format Logic /tb_fir_semi_parallel/din_vld
|
||||||
|
add wave -noupdate -format Literal -expand /tb_fir_semi_parallel/uut/count_array
|
||||||
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/coef_array
|
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/coef_array
|
||||||
add wave -noupdate -format Literal -expand /tb_fir_semi_parallel/uut/ce_array
|
add wave -noupdate -format Literal -expand /tb_fir_semi_parallel/uut/ce_array
|
||||||
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/h_addr
|
add wave -noupdate -format Literal /tb_fir_semi_parallel/uut/h_addr
|
||||||
@@ -40,7 +43,7 @@ add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_
|
|||||||
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/x_out
|
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/x_out
|
||||||
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/y_out
|
add wave -noupdate -format Literal -radix decimal /tb_fir_semi_parallel/uut/gen_stages__1/inst_fir_stage/y_out
|
||||||
TreeUpdate [SetDefaultTree]
|
TreeUpdate [SetDefaultTree]
|
||||||
WaveRestoreCursors {{Cursor 1} {256495124 ps} 0}
|
WaveRestoreCursors {{Cursor 1} {345579170 ps} 0} {{Cursor 2} {119566178 ps} 0} {{Cursor 3} {62144258 ps} 0}
|
||||||
configure wave -namecolwidth 150
|
configure wave -namecolwidth 150
|
||||||
configure wave -valuecolwidth 100
|
configure wave -valuecolwidth 100
|
||||||
configure wave -justifyvalue left
|
configure wave -justifyvalue left
|
||||||
@@ -54,4 +57,4 @@ configure wave -gridperiod 100
|
|||||||
configure wave -griddelta 40
|
configure wave -griddelta 40
|
||||||
configure wave -timeline 1
|
configure wave -timeline 1
|
||||||
update
|
update
|
||||||
WaveRestoreZoom {0 ps} {420 us}
|
WaveRestoreZoom {0 ps} {126 us}
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ Port
|
|||||||
(
|
(
|
||||||
rst : in std_logic;
|
rst : in std_logic;
|
||||||
clk : in std_logic;
|
clk : in std_logic;
|
||||||
ce : in std_logic;
|
|
||||||
h_addr : in natural range 0 to nstages*ntaps_per_stage-1;
|
h_addr : in natural range 0 to nstages*ntaps_per_stage-1;
|
||||||
h_we : in std_logic;
|
h_we : in std_logic;
|
||||||
h_in : in sfixed;
|
h_in : in sfixed;
|
||||||
@@ -77,7 +76,7 @@ architecture Behavioral of fir_semi_parallel is
|
|||||||
type coef_stage_array_t is array (0 to ntaps_per_stage-1) of coef_t;
|
type coef_stage_array_t is array (0 to ntaps_per_stage-1) of coef_t;
|
||||||
type coef_array_t is array (0 to nstages-1) of coef_stage_array_t;
|
type coef_array_t is array (0 to nstages-1) of coef_stage_array_t;
|
||||||
subtype count_t is natural range 0 to ntaps_per_stage-1;
|
subtype count_t is natural range 0 to ntaps_per_stage-1;
|
||||||
type count_array_t is array (0 to nstages-1) of count_t;
|
type count_array_t is array (nstages-1 downto 0) of count_t;
|
||||||
|
|
||||||
subtype stage_t is sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
|
subtype stage_t is sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
|
||||||
type stage_array_t is array (0 to nstages) of stage_t;
|
type stage_array_t is array (0 to nstages) of stage_t;
|
||||||
@@ -87,7 +86,7 @@ architecture Behavioral of fir_semi_parallel is
|
|||||||
signal coef_stage : coef_stage_t;
|
signal coef_stage : coef_stage_t;
|
||||||
signal count0 : count_t;
|
signal count0 : count_t;
|
||||||
signal ce0 : std_logic;
|
signal ce0 : std_logic;
|
||||||
signal ce_array : unsigned(0 to nstages);
|
signal ce_array : unsigned(nstages downto 0);
|
||||||
signal coef_addr : unsigned(coef_addr_nbits-1 downto 0);
|
signal coef_addr : unsigned(coef_addr_nbits-1 downto 0);
|
||||||
signal stage_addr : unsigned(NextExpBaseTwo(nstages)-1 downto 0);
|
signal stage_addr : unsigned(NextExpBaseTwo(nstages)-1 downto 0);
|
||||||
|
|
||||||
@@ -95,10 +94,12 @@ architecture Behavioral of fir_semi_parallel is
|
|||||||
SIGNAL xo : stage_array_t;
|
SIGNAL xo : stage_array_t;
|
||||||
SIGNAL y : stage_array_t;
|
SIGNAL y : stage_array_t;
|
||||||
SIGNAL accu : sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
|
SIGNAL accu : sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac));
|
||||||
signal accu_load : std_logic;
|
|
||||||
|
|
||||||
|
signal en : std_logic;
|
||||||
|
signal accu_load : std_logic;
|
||||||
signal accu_ld_pipe : unsigned(input_latency+coef_latency+pipe_latency downto 0);
|
signal accu_ld_pipe : unsigned(input_latency+coef_latency+pipe_latency downto 0);
|
||||||
signal vld_pipe : unsigned(1 downto 0);
|
|
||||||
|
signal din_r : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac));
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
begin
|
begin
|
||||||
@@ -108,21 +109,18 @@ begin
|
|||||||
coef_addr <= to_unsigned(h_addr, coef_addr_nbits);
|
coef_addr <= to_unsigned(h_addr, coef_addr_nbits);
|
||||||
stage_addr <= coef_addr(coef_addr'left downto NextExpBaseTwo(ntaps_per_stage));
|
stage_addr <= coef_addr(coef_addr'left downto NextExpBaseTwo(ntaps_per_stage));
|
||||||
|
|
||||||
x(0) <= resize(din, x(0));
|
x(0) <= resize(din_r, x(0));
|
||||||
y(0) <= to_sfixed(0.0, y(0));
|
y(0) <= to_sfixed(0.0, y(0));
|
||||||
|
|
||||||
accu_load <= accu_ld_pipe(accu_ld_pipe'left);
|
accu_load <= accu_ld_pipe(accu_ld_pipe'left);
|
||||||
dout_vld <= vld_pipe(vld_pipe'left) and ce0;
|
rdy <= '1';
|
||||||
rdy <= ce0;
|
|
||||||
|
|
||||||
valid_pipe:
|
din_register:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
if rst = '1' then
|
if din_vld = '1' then
|
||||||
vld_pipe <= (others => '0');
|
din_r <= din;
|
||||||
elsif ce0 = '1' then
|
|
||||||
vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & din_vld;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
@@ -131,14 +129,11 @@ accu_load_pipe:
|
|||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
accu_ld_pipe(0) <= ce_array(nstages-1);
|
|
||||||
for i in 1 to accu_ld_pipe'length-1 loop
|
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
accu_ld_pipe(i) <= '0';
|
accu_ld_pipe <= (others => '0');
|
||||||
else
|
elsif en = '1' then
|
||||||
accu_ld_pipe(i) <= accu_ld_pipe(i-1);
|
accu_ld_pipe <= accu_ld_pipe(accu_ld_pipe'left-1 downto 0) & ce_array(nstages-1);
|
||||||
end if;
|
end if;
|
||||||
end loop;
|
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
@@ -162,7 +157,7 @@ coef_read:
|
|||||||
variable i : natural range 0 to nstages-1;
|
variable i : natural range 0 to nstages-1;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) and en = '1' then
|
||||||
for i in 0 to nstages-1 loop
|
for i in 0 to nstages-1 loop
|
||||||
coef_stage(i) <= coef_array(i)(count_array(i));
|
coef_stage(i) <= coef_array(i)(count_array(i));
|
||||||
end loop;
|
end loop;
|
||||||
@@ -177,11 +172,14 @@ counter:
|
|||||||
ce0 <= '0';
|
ce0 <= '0';
|
||||||
count0 <= cnt;
|
count0 <= cnt;
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
cnt := 0;
|
en <= '0';
|
||||||
else
|
cnt := count_t'high;
|
||||||
if cnt /= count_t'high then
|
elsif cnt /= count_t'high then
|
||||||
cnt := cnt + 1;
|
cnt := cnt + 1;
|
||||||
else
|
else
|
||||||
|
en <= '0';
|
||||||
|
if din_vld = '1' then
|
||||||
|
en <= '1';
|
||||||
cnt := 0;
|
cnt := 0;
|
||||||
ce0 <= '1';
|
ce0 <= '1';
|
||||||
end if;
|
end if;
|
||||||
@@ -192,13 +190,8 @@ counter:
|
|||||||
cnt_pipe:
|
cnt_pipe:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) and en = '1' then
|
||||||
count_array(0) <= count0;
|
count_array <= count_array(count_array'left-1 downto 0) & count0;
|
||||||
for i in 1 to nstages-1 loop
|
|
||||||
if rst = '0' then
|
|
||||||
count_array(i) <= count_array(i-1);
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
@@ -206,14 +199,11 @@ ce_pipe:
|
|||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
ce_array(0) <= ce0;
|
|
||||||
for i in 1 to nstages loop
|
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
ce_array(i) <= '0';
|
ce_array <= (others => '0');
|
||||||
else
|
elsif en = '1' then
|
||||||
ce_array(i) <= ce_array(i-1);
|
ce_array <= ce_array(ce_array'left-1 downto 0) & ce0;
|
||||||
end if;
|
end if;
|
||||||
end loop;
|
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
@@ -235,7 +225,7 @@ gen_stages:
|
|||||||
(
|
(
|
||||||
rst => rst,
|
rst => rst,
|
||||||
clk => clk,
|
clk => clk,
|
||||||
ce => ce,
|
ce => en,
|
||||||
x_in => x(i+1),
|
x_in => x(i+1),
|
||||||
y_in => y(i),
|
y_in => y(i),
|
||||||
h_in => coef_stage(i),
|
h_in => coef_stage(i),
|
||||||
@@ -259,7 +249,8 @@ gen_delays:
|
|||||||
PORT MAP
|
PORT MAP
|
||||||
(
|
(
|
||||||
clk => clk,
|
clk => clk,
|
||||||
ce => ce_array(i),
|
ce => en,
|
||||||
|
shift_en => ce_array(i),
|
||||||
delay => count_array(i),
|
delay => count_array(i),
|
||||||
din => x(i),
|
din => x(i),
|
||||||
dout => x(i+1)
|
dout => x(i+1)
|
||||||
@@ -269,7 +260,8 @@ gen_delays:
|
|||||||
acumulator:
|
acumulator:
|
||||||
process(clk)
|
process(clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) and en = '1' then
|
||||||
|
dout_vld <= accu_load;
|
||||||
if accu_load = '1' then
|
if accu_load = '1' then
|
||||||
dout <= resize(accu, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac));
|
dout <= resize(accu, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac));
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ use work.PCK_FIO.all;
|
|||||||
ENTITY tb_fir_semi_parallel IS
|
ENTITY tb_fir_semi_parallel IS
|
||||||
Generic
|
Generic
|
||||||
(
|
(
|
||||||
ntaps_per_stage : integer := 16;
|
ntaps_per_stage : integer := 4;
|
||||||
nstages : integer := 2;
|
nstages : integer := 8;
|
||||||
nbits_in : integer := 32;
|
nbits_in : integer := 32;
|
||||||
nbits_in_frac : integer := 30;
|
nbits_in_frac : integer := 30;
|
||||||
nbits_stages : integer := 32;
|
nbits_stages : integer := 32;
|
||||||
@@ -114,7 +114,6 @@ BEGIN
|
|||||||
(
|
(
|
||||||
rst => rst,
|
rst => rst,
|
||||||
clk => clk,
|
clk => clk,
|
||||||
ce => '1',
|
|
||||||
h_addr => h_addr,
|
h_addr => h_addr,
|
||||||
h_we => h_we,
|
h_we => h_we,
|
||||||
h_in => h_in,
|
h_in => h_in,
|
||||||
@@ -157,6 +156,10 @@ BEGIN
|
|||||||
h_we <= '1';
|
h_we <= '1';
|
||||||
end loop;
|
end loop;
|
||||||
wait until rising_edge(clk);
|
wait until rising_edge(clk);
|
||||||
|
h_addr <= 0;
|
||||||
|
h_in <= to_sfixed(0.25, h_in);
|
||||||
|
h_we <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
h_we <= '0';
|
h_we <= '0';
|
||||||
|
|
||||||
d_in <= to_sfixed(0.0, d_in);
|
d_in <= to_sfixed(0.0, d_in);
|
||||||
@@ -177,17 +180,30 @@ BEGIN
|
|||||||
din_vld <= '0';
|
din_vld <= '0';
|
||||||
|
|
||||||
wait for 64*ntaps*PERIOD;
|
wait for 64*ntaps*PERIOD;
|
||||||
|
|
||||||
|
wait until rising_edge(clk) and rdy = '1';
|
||||||
|
din_vld <= '1';
|
||||||
|
d_in <= to_sfixed(1.0, d_in);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
din_vld <= '0';
|
||||||
|
|
||||||
|
wait for 10*PERIOD;
|
||||||
wait until rising_edge(clk) and rdy = '1';
|
wait until rising_edge(clk) and rdy = '1';
|
||||||
din_vld <= '1';
|
din_vld <= '1';
|
||||||
d_in <= to_sfixed(0.0, d_in);
|
d_in <= to_sfixed(0.0, d_in);
|
||||||
wait until rising_edge(clk) and rdy = '1';
|
wait until rising_edge(clk);
|
||||||
d_in <= to_sfixed(1.0, d_in);
|
|
||||||
wait until rising_edge(clk) and rdy = '1';
|
|
||||||
d_in <= to_sfixed(0.0, d_in);
|
|
||||||
wait for 64*ntaps*PERIOD;
|
|
||||||
wait until rising_edge(clk) and rdy = '1';
|
|
||||||
din_vld <= '0';
|
din_vld <= '0';
|
||||||
|
|
||||||
|
for i in 0 to 9999 loop
|
||||||
|
wait for 2*PERIOD;
|
||||||
|
wait until rising_edge(clk) and rdy = '1';
|
||||||
|
din_vld <= '1';
|
||||||
|
d_in <= to_sfixed(0.0, d_in);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
din_vld <= '0';
|
||||||
|
|
||||||
|
end loop;
|
||||||
|
|
||||||
wait for 40*PERIOD;
|
wait for 40*PERIOD;
|
||||||
|
|
||||||
assert false report "Test finished" severity error;
|
assert false report "Test finished" severity error;
|
||||||
|
|||||||
Reference in New Issue
Block a user