我尝试在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;
如果任何人可以提供帮助,我会很感激。我认为它与信号c_i和s_i的初始值有关,但我不太确定。
答案 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
值表示未初始化的值。
因此,您的代码的行为与您预期的一样。如果您对该行为不满意,则需要添加重置输入并将其连接到触发器。