网站建设 投资合作在线做初中题网站
Vivado合成直接从RTL中推导出乘加级联来组成FIR滤波器。这种滤波器有几种可能的实现方式;一个例子是收缩滤波器在7系列DSP48E1 Slice用户指南(UG479)中进行了描述,并在8抽头偶数中显示对称收缩FIR(Verilog)。从编码示例下载编码示例文件。
 8-Tap Even Symmetric Systolic FIR (Verilog)  
 
 Filename: sfir_even_symetric_systolic_top.v  
 
 // sfir_even_symmetric_systolic_top.v  
 
 // FIR Symmetric Systolic Filter, Top module is  
 
 sfir_even_symmetric_systolic_top  
 
 // sfir_shifter - sub module which is used in top level  
 
 (* dont_touch = "yes" *)  
 
 module sfir_shifter #(parameter dsize = 16, nbtap = 4)  
 
 (input clk, [dsize-1:0] datain, output [dsize-1:0] dataout);  
 
 (* srl_style = "srl_register" *) reg [dsize-1:0] tmp [0:2*nbtap-1];  
 
 integer i;  
 
 always @(posedge clk)  
 
 begin  
 
 tmp[0] <= datain;  
 
 for (i=0; i<=2*nbtap-2; i=i+1)  
 
 tmp[i+1] <= tmp[i];  
 
 end  
 
 assign dataout = tmp[2*nbtap-1];  
 
 endmodule  
 
 // sfir_even_symmetric_systolic_element - sub module which is used in top  
 
 module sfir_even_symmetric_systolic_element #(parameter dsize = 16)  
 
 (input clk, input signed [dsize-1:0] coeffin, datain, datazin, input signed  
 
 [2*dsize-1:0] cascin,  
 
 output signed [dsize-1:0] cascdata, output reg signed [2*dsize-1:0]  
 
 cascout);  
 
 reg signed [dsize-1:0] coeff;  
 
 reg signed [dsize-1:0] data;  
 
 reg signed [dsize-1:0] dataz;  
 
 reg signed [dsize-1:0] datatwo; 
 
 reg signed [dsize:0] preadd;  
  reg signed [2*dsize-1:0] product;  
  assign cascdata = datatwo;  
  always @(posedge clk)  
  begin  
  coeff <= coeffin;  
  data <= datain;  
  datatwo <= data;  
  dataz <= datazin;  
  preadd <= datatwo + dataz;  
  product <= preadd * coeff;  
  cascout <= product + cascin;  
  end  
  endmodule  
  module sfir_even_symmetric_systolic_top #(parameter nbtap = 4, dsize = 16,  
  psize = 2*dsize)  
  (input clk, input signed [dsize-1:0] datain, output signed [2*dsize-1:0]  
  firout);  
  wire signed [dsize-1:0] h [nbtap-1:0];  
  wire signed [dsize-1:0] arraydata [nbtap-1:0];  
  wire signed [psize-1:0] arrayprod [nbtap-1:0];  
  wire signed [dsize-1:0] shifterout;  
  reg signed [dsize-1:0] dataz [nbtap-1:0];  
  assign h[0] = 7;  
  assign h[1] = 14;  
  assign h[2] = -138;  
  assign h[3] = 129;  
  assign firout = arrayprod[nbtap-1]; // Connect last product to output  
  sfir_shifter #(dsize, nbtap) shifter_inst0 (clk, datain, shifterout);  
  generate  
  genvar I;  
  for (I=0; I<nbtap; I=I+1)  
  if (I==0)  
  sfir_even_symmetric_systolic_element #(dsize) fte_inst0 (clk, h[I], datain,  
  shifterout, {32{1'b0}}, arraydata[I], arrayprod[I]);  
  else  
  sfir_even_symmetric_systolic_element #(dsize) fte_inst (clk, h[I],  
  arraydata[I-1], shifterout, arrayprod[I-1], arraydata[I], arrayprod[I]);  
  endgenerate  
  endmodule // sfir_even_symmetric_systolic_top 
   8-Tap Even Symmetric Systolic FIR (VHDL)  
  Filename: sfir_even_symetric_systolic_top.vhd  
  --  
  -- FIR filter top  
  -- File: sfir_even_symmetric_systolic_top.vhd  
  -- FIR filter shifter  
  -- submodule used in top (sfir_even_symmetric_systolic_top)  
  library ieee;  
  use ieee.std_logic_1164.all;  
  entity sfir_shifter is  
  generic(  
  DSIZE : natural := 16;  
  NBTAP : natural := 4  
  );  
  port(  
  clk : in std_logic;  
  datain : in std_logic_vector(DSIZE - 1 downto 0);  
  dataout : out std_logic_vector(DSIZE - 1 downto 0)  
  );  
  end sfir_shifter;  
  architecture rtl of sfir_shifter is  
  -- Declare signals  
  --  
  type CHAIN is array (0 to 2 * NBTAP - 1) of std_logic_vector(DSIZE - 1  
  downto 0);  
  signal tmp : CHAIN;  
  begin  
  process(clk)  
  begin  
  if rising_edge(clk) then  
  tmp(0) <= datain;  
  looptmp : for i in 0 to 2 * NBTAP - 2 loop  
  tmp(i + 1) <= tmp(i);  
  end loop;  
  end if;  
  end process;  
  dataout <= tmp(2 * NBTAP - 1);  
  end rtl;  
  --  
  -- FIR filter engine (multiply with pre-add and post-add)  
  -- submodule used in top (sfir_even_symmetric_systolic_top)  
  library ieee;  
  use ieee.std_logic_1164.all;  
  use ieee.numeric_std.all;  
  entity sfir_even_symmetric_systolic_element is  
  generic(DSIZE : natural := 16);  
  port(clk : in std_logic;  
  coeffin, datain, datazin : in std_logic_vector(DSIZE - 1 downto 0);  
  cascin : in std_logic_vector(2 * DSIZE downto 0);  
  cascdata : out std_logic_vector(DSIZE - 1 downto 0);  
  cascout : out std_logic_vector(2 * DSIZE downto 0));  
  end sfir_even_symmetric_systolic_element;  
  architecture rtl of sfir_even_symmetric_systolic_element is  
  -- Declare signals  
  --  
  signal coeff, data, dataz, datatwo : signed(DSIZE - 1 downto 0);  
  signal preadd : signed(DSIZE downto 0);  
  signal product, cascouttmp : signed(2 * DSIZE downto 0);  
  begin  
  process(clk)  
  begin  
  if rising_edge(clk) then  
  coeff <= signed(coeffin);  
  data <= signed(datain);  
  datatwo <= data;  
  dataz <= signed(datazin);  
  preadd <= resize(datatwo, DSIZE + 1) + resize(dataz, DSIZE + 1);  
  product <= preadd * coeff;  
  cascouttmp <= product + signed(cascin);  
  end if;  
  end process;  
  -- Type conversion for output  
  --  
  cascout <= std_logic_vector(cascouttmp);  
  cascdata <= std_logic_vector(datatwo);  
  end rtl;  
  library ieee;  
  use ieee.std_logic_1164.all;  
  use ieee.numeric_std.all;  
  entity sfir_even_symmetric_systolic_top is  
  generic(NBTAP : natural := 4;  
  DSIZE : natural := 16;  
  PSIZE : natural := 33);  
  port(clk : in std_logic;  
  datain : in std_logic_vector(DSIZE - 1 downto 0);  
  firout : out std_logic_vector(PSIZE - 1 downto 0));  
  end sfir_even_symmetric_systolic_top;  
  architecture rtl of sfir_even_symmetric_systolic_top is  
  -- Declare signals  
  --  
  type DTAB is array (0 to NBTAP - 1) of std_logic_vector(DSIZE - 1 downto 0);  
  type HTAB is array (0 to NBTAP - 1) of std_logic_vector(0 to DSIZE - 1);  
  type PTAB is array (0 to NBTAP - 1) of std_logic_vector(PSIZE - 1 downto 0);  
  signal arraydata, dataz : DTAB;  
  signal arrayprod : PTAB;  
  signal shifterout : std_logic_vector(DSIZE - 1 downto 0);  
  -- Initialize coefficients and a "zero" for the first filter element  
  --  
  constant h : HTAB := ((std_logic_vector(TO_SIGNED(63, DSIZE))),  
  (std_logic_vector(TO_SIGNED(18, DSIZE))),  
  (std_logic_vector(TO_SIGNED(-100, DSIZE))),  
  (std_logic_vector(TO_SIGNED(1, DSIZE))));  
  constant zero_psize : std_logic_vector(PSIZE - 1 downto 0) := (others =>  
  '0');  
  begin  
  -- Connect last product to output  
  --  
  firout <= arrayprod(nbtap - 1);  
  -- Shifter  
  --  
  shift_u0 : entity work.sfir_shifter  
  generic map(DSIZE, NBTAP)  
  port map(clk, datain, shifterout);  
  -- Connect the arithmetic building blocks of the FIR  
  --  
  gen : for I in 0 to NBTAP - 1 generate  
  begin  
  g0 : if I = 0 generate  
  element_u0 : entity work.sfir_even_symmetric_systolic_element  
  generic map(DSIZE)  
  port map(clk, h(I), datain, shifterout, zero_psize, arraydata(I),  
  arrayprod(I));  
  end generate g0;  
  gi : if I /= 0 generate  
  element_ui : entity work.sfir_even_symmetric_systolic_element  
  generic map(DSIZE)  
  port map(clk, h(I), arraydata(I - 1), shifterout, arrayprod(I - 1),  
  arraydata(I), arrayprod(I));  
  end generate gi;  
  end generate gen;  
  end rtl;  
 