OpenCores
URL https://opencores.org/ocsvn/astron_filter/astron_filter/trunk

Subversion Repositories astron_filter

[/] [astron_filter/] [trunk/] [fil_ppf_filter.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2012
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
-- Purpose: A FIR filter implementation. 
22
--
23
-- Description: This unit instantiates a multiplier for every tap. 
24
--              All output of the mutipliers are added using an 
25
--              adder-tree structure. 
26
--              
27
-- Remarks:    .
28
--              
29
 
30
library IEEE, common_pkg_lib, astron_multiplier_lib, astron_requantize_lib, astron_adder_lib;
31
use IEEE.std_logic_1164.ALL;
32
use IEEE.numeric_std.ALL;
33
--USE technology_lib.technology_select_pkg.ALL;
34
use common_pkg_lib.common_pkg.ALL;
35
use work.fil_pkg.ALL;
36
 
37
entity fil_ppf_filter is
38
  generic (
39
    g_technology       : NATURAL := 0;
40
    g_fil_ppf          : t_fil_ppf;
41
    g_fil_ppf_pipeline : t_fil_ppf_pipeline
42
  );
43
  port (
44
    clk        : in  std_logic;
45
    rst        : in  std_logic;
46
    taps       : in  std_logic_vector;
47
    coefs      : in  std_logic_vector;
48
    result     : out std_logic_vector
49
  );
50
end fil_ppf_filter;
51
 
52
architecture rtl of fil_ppf_filter is
53
 
54
  constant c_in_dat_w       : natural := g_fil_ppf.backoff_w + g_fil_ppf.in_dat_w;        -- add optional input backoff to fit output overshoot
55
  constant c_prod_w         : natural := c_in_dat_w + g_fil_ppf.coef_dat_w - c_sign_w;    -- skip double sign bit
56
  constant c_gain_w         : natural := 0;   -- no need for adder bit growth so fixed 0, because filter coefficients should have DC gain <= 1.
57
                                              -- The adder tree bit growth depends on DC gain of FIR coefficients, not on ceil_log2(g_fil_ppf.nof_taps).
58
  constant c_sum_w          : natural := c_prod_w + c_gain_w;
59
  constant c_ppf_lsb_w      : natural := c_sum_w - g_fil_ppf.out_dat_w;
60
 
61
  signal prod_vec     : std_logic_vector(g_fil_ppf.nof_taps*c_prod_w-1 downto 0);
62
  signal adder_out    : std_logic_vector(c_sum_w-1 downto 0) := (others => '0');
63
  signal requant_out  : std_logic_vector(g_fil_ppf.out_dat_w-1 downto 0);
64
 
65
  signal in_taps         : std_logic_vector(g_fil_ppf.in_dat_w*g_fil_ppf.nof_taps-1 downto 0);  -- taps input data as stored in RAM
66
  signal in_taps_backoff : std_logic_vector(        c_in_dat_w*g_fil_ppf.nof_taps-1 downto 0);  -- taps input data with backoff as use in FIR
67
 
68
begin
69
 
70
  in_taps <= taps;  -- Use this help signal to create a 'HIGH downto 0 vector again.   
71
  ---------------------------------------------------------------
72
  -- GENERATE THE MUTIPLIERS
73
  ---------------------------------------------------------------
74
  -- For every tap a unique multiplier is instantiated that 
75
  -- multiplies the data tap with the corresponding filter coefficient
76
  gen_multipliers : for I in 0 to g_fil_ppf.nof_taps-1 generate
77
    in_taps_backoff((I+1)*c_in_dat_w-1 downto I*c_in_dat_w) <= resize_svec(in_taps((I+1)*g_fil_ppf.in_dat_w-1 downto I*g_fil_ppf.in_dat_w), c_in_dat_w);
78
 
79
    u_multiplier : entity astron_multiplier_lib.common_mult
80
    generic map (
81
      g_technology       => g_technology,
82
      g_variant          => "IP",
83
      g_in_a_w           => c_in_dat_w,
84
      g_in_b_w           => g_fil_ppf.coef_dat_w,
85
      g_out_p_w          => c_prod_w,
86
      g_nof_mult         => 1,
87
      g_pipeline_input   => g_fil_ppf_pipeline.mult_input,
88
      g_pipeline_product => g_fil_ppf_pipeline.mult_product,
89
      g_pipeline_output  => g_fil_ppf_pipeline.mult_output,
90
      g_representation   => "SIGNED"
91
    )
92
    port map (
93
      rst      => rst,
94
      clk      => clk,
95
      clken    => '1',
96
      in_a     => in_taps_backoff((I+1)*c_in_dat_w-1 downto I*c_in_dat_w),
97
      in_b     => coefs((I+1)*g_fil_ppf.coef_dat_w-1 downto I*g_fil_ppf.coef_dat_w),
98
      out_p    => prod_vec((I+1)*c_prod_w-1 downto I*c_prod_w)
99
    );
100
  end generate;
101
 
102
  ---------------------------------------------------------------
103
  -- ADDER TREE
104
  ---------------------------------------------------------------  
105
  -- The adder tree summarizes the outputs of all multipliers.
106
  u_adder_tree : entity astron_adder_lib.common_adder_tree(str)
107
  generic map (
108
    g_representation => "SIGNED",
109
    g_pipeline       => g_fil_ppf_pipeline.adder_stage,
110
    g_nof_inputs     => g_fil_ppf.nof_taps,
111
    g_dat_w          => c_prod_w,
112
    g_sum_w          => c_sum_w
113
  )
114
  port map (
115
    clk    => clk,
116
    in_dat => prod_vec,
117
    sum    => adder_out
118
  );
119
 
120
  u_requantize_addeer_output : entity astron_requantize_lib.common_requantize
121
  generic map (
122
    g_representation      => "SIGNED",
123
    g_lsb_w               => c_ppf_lsb_w,
124
    g_lsb_round           => TRUE,
125
    g_lsb_round_clip      => FALSE,
126
    g_msb_clip            => FALSE,
127
    g_msb_clip_symmetric  => FALSE,
128
    g_pipeline_remove_lsb => g_fil_ppf_pipeline.requant_remove_lsb,
129
    g_pipeline_remove_msb => g_fil_ppf_pipeline.requant_remove_msb,
130
    g_in_dat_w            => c_sum_w,
131
    g_out_dat_w           => g_fil_ppf.out_dat_w
132
  )
133
  port map (
134
    clk        => clk,
135
    clken      => '1',
136
    in_dat     => adder_out,
137
    out_dat    => requant_out,
138
    out_ovr    => open
139
  );
140
 
141
  result <= RESIZE_SVEC(requant_out, result'LENGTH);
142
 
143
end rtl;
144
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.