【问题标题】:VHDL Filter not getting output for first valuesVHDL过滤器没有获得第一个值的输出
【发布时间】:2018-05-09 23:26:42
【问题描述】:

我尝试在 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).

源文件(我还有另外 2 个用于 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;

输出:

如果有人能提供帮助,我将不胜感激。我认为这与信号 c_i 和 s_i 的初始值有关,但我不太确定。

【问题讨论】:

    标签: vhdl


    【解决方案1】:

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

    因此,您的代码的行为符合您的预期。如果您对这种行为不满意,则需要添加一个复位输入并将其连接到您的触发器。

    【讨论】:

    • 什么时候应该将复位引脚从 1 转为 0?
    • VHDL 是一种硬件描述语言。你在这里设计数字硬件。我认为你需要学习一些基本的数字电子学,特别是关于触发器和同步/异步复位的知识。
    【解决方案2】:

    您已经构建了一系列三个寄存器,组成了级联的寄存器。
    您尚未提供重置,因此寄存器内容将是未知的。您可以在没有任何条件的情况下使用寄存器进行计算。因此,您的算术计算将看到 Unknown 值并如您所见那样失败。

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

    真正正确的方法是将“有效”信号与数据一起传输。仅当存在“有效”时才显示输出数据。这是通过任何管道硬件结构处理数据的标准方法。

    顺便说一句:您通常自己构建 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 切换到 0?如何在不明确使用 D-ffs 的情况下创建此电路?
    猜你喜欢
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    相关资源
    最近更新 更多