VHDL过滤器未获得第一个值的输出

时间:2018-05-09 14:21:51

标签: vhdl

我尝试在VHDL中实现一个fir过滤器,但在前三个时钟中我没有输出和错误at 0 ps, Instance /filter_tb/uut/ : Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).

源文件(我还有另外两个用于D触发器的文件):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;


entity filter is
    port ( x: in STD_LOGIC_VECTOR(3 downto 0);
            clk: in STD_LOGIC;
            y: out STD_LOGIC_VECTOR(9 downto 0));
end filter;


architecture struct of filter is


    type array1 is array (0 to 3) of STD_LOGIC_VECTOR(3 downto 0);
    signal coef : array1 :=( "0001", "0011", "0010", "0001");

    signal c0, c1, c2, c3: STD_LOGIC_VECTOR(7 downto 0):="00000000";    
    signal s0, s1, s2, s3: STD_LOGIC_VECTOR(3 downto 0) :="0000";
    signal sum: STD_LOGIC_VECTOR(9 downto 0):="0000000000";


    component DFF is
        Port ( d : in  STD_LOGIC_VECTOR(3 downto 0);
                clk : in  STD_LOGIC;
                q : out  STD_LOGIC_VECTOR(3 downto 0));
    end component;

    component lDFF is
        Port ( d : in  STD_LOGIC_VECTOR(9 downto 0);
                clk : in  STD_LOGIC;
                q : out  STD_LOGIC_VECTOR(9 downto 0));
    end component;

begin       

        s0<=x;
        c0<=x*coef(0);  
        DFF1: DFF port map(s0,clk,s1);
        c1<=s1*coef(1);     
        DFF2: DFF port map(s1,clk,s2);
        c2<=s2*coef(2);     
        DFF3: DFF port map(s2,clk,s3);
        c3<=s3*coef(3);
        sum<=("00" & c0+c1+c2+c3);
        lDFF1: lDFF port map(sum,clk,y);

end struct;

测试平台:

    LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.std_logic_unsigned.all;

ENTITY filter_tb IS
END filter_tb;

ARCHITECTURE behavior OF filter_tb IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT filter
    PORT(
         x : IN  STD_LOGIC_VECTOR(3 downto 0);
         clk : IN  std_logic;
         y : OUT STD_LOGIC_VECTOR(9 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal x : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
   signal clk : std_logic := '0';

    --Outputs
   signal y : STD_LOGIC_VECTOR(9 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;


BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: filter PORT MAP (
          x => x,
          clk => clk,
          y => y
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc1: process
   begin        

      x<="0001";
        wait for 10ns;
        x<="0011";
        wait for 10ns;
        x<="0010";
        wait for 10ns;
        --x<="0011";


   end process;

END;

输出: Output

如果任何人可以提供帮助,我会很感激。我认为它与信号c_i和s_i的初始值有关,但我不太确定。

2 个答案:

答案 0 :(得分:1)

你已经建立了一系列三个寄存器组成一系列寄存器 您尚未提供重置,因此注册内容将为“未知”。您可以无任何条件地使用寄存器进行计算。因此,算术计算将看到未知值并失败,如您所见。

第一个(最简单的)解决方案是添加重置。但这不是最好的解决方案。您将不再收到警告,但输出的前三个周期将基于寄存器复位值而非输入信号。
如果你有一个很大的流,并且不关心第一个时钟周期中的一些不正确的值,你可以忍受它。

真正正确的方法是拥有一个有效的&#39;信号沿着您的数据传输。只有有效的&#39;时才会显示输出数据。这是通过任何管道硬件结构处理数据的标准方法。

顺便说一下:你通常自己构建D-ffs。合成器将为您做到这一点。您只需使用时钟进程并处理其中的数据向量。

  

我有一些问题。如果我添加一个复位引脚,我何时将它从1切换到0?如何在不明确使用D-ffs的情况下创建此电路?

您可以像制作时钟一样制作复位信号。

对于D寄存器:如果使用标准寄存器VHDL代码,它们会出现:

reg : process (clk,reset_n)
begin
   // a-synchronous active low reset
   if (reset_n='0') then 
      s0 <= "0000";
      s1 <= "0000";
      s2 <= "0000";
    elsif (rising_edge(clk)) then
      s0 <= x;
      s1 <= s0;
      s2 <= s1;
 ....

(代码按原样输入,未检查语法或输入错误)

答案 1 :(得分:1)

您的FIR滤波器包含触发器。这些触发器没有复位输入,因此在未知状态下上电。你通过初始化触发器模拟器模拟这个模型。输出到"UUUU"(因为它是四位宽)。 'U' std_logic值表示未初始化的值。

因此,您的代码的行为与您预期的一样。如果您对该行为不满意,则需要添加重置输入并将其连接到触发器。