1

这是代码:

entity main is
port(input:in unsigned(99 downto 0);
clk:in std_logic;
output:out unsigned(99 downto 0)
);
end main;

architecture Behavioral of main is

begin

process(clk)

variable x:unsigned(99 downto 0):=X"27c8a94a6fb72a00000000000";
begin
if(clk'event and clk='1') then

x:=(x*input);// this line is a problem!!

output<=x;
x:=X"27c8a94a6fb72a00000000000";// i have to rest x manually :S

end if;
end process;
end Behavioral;

第一个问题是 x 虽然是一个变量并且应该在每次进程运行时重置它并没有保存它的值!我在模拟中一步一步地看到了它。第二个问题是,虽然输入是固定到这个实体的,并且不会因每个 clk 进程而改变 x 要么是 x * 输入(正确答案)或 0(错误答案),但当我的时钟停止滴答作响时,它会停在 0 答案,如果我稍微减少时钟它可能会停在正确的答案(即输入x)我的问题是为什么输入x 不固定如果输入和 x 是固定的,第二个是为什么当再次调用进程时 x 不重置(来自它的敏感度列表)。这是测试代码:


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.numeric_std.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY test IS
END test;

ARCHITECTURE behavior OF test IS 

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

    COMPONENT main
    PORT(
         input : IN  unsigned(99 downto 0);
         clk : IN  std_logic;
         output : OUT  unsigned(99 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal input : unsigned(99 downto 0) := (others => '0');
   signal clk : std_logic := '0';

    --Outputs
   signal output : unsigned(99 downto 0);

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

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: main PORT MAP (
          input => input,
          clk => clk,
          output => output
        );

   -- 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_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  
input<=X"000000000000000000000000F";
--input<="000000000001";
      wait for clk_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;

///

请注意,在测试开始时,该过程在没有插入输入值的情况下运行了几次,在这种情况下,我不关心结果,我说的是在插入输入时会发生此问题。

4

2 回答 2

1

首先要了解的是,您永远不会调用进程!

一个进程只启动一次 - 因此变量只初始化一次。

它运行到完成并休眠 - 下一个时钟事件将其唤醒,并在每个时钟周期中从开始到完成执行。

将进程想象成带有事件循环的 C 主程序可能会有所帮助。它会一直休眠直到事件发生,并且您声明的变量是全局变量(或“静态”变量 - 它保留其最后一个值)。

如果你想要一个 C 函数或过程的效果(cough , void 函数),写一个 VHDL 函数或过程;每次在进程中调用它们时,这些局部变量都会重新初始化。

因此,在 1 个时钟周期后您会看到x * input,在几个时钟周期后,您会看到其中最不重要的 100 位x * input * input * input ... * input,由于乘法字的增长,最终将全部为 0。

如果您要做的只是将每个新输入乘以 X 的初始值,那么您最好将 X 声明为常量,并简单地编写:

process(clk)
constant x:unsigned(99 downto 0):=X"27c8a94a6fb72a00000000000";
begin
   if rising_edge(clk) then
      output <= x * input;
   end if;
end process;
于 2013-03-14T16:11:40.450 回答
0

问题是,您将 2 个长度为 100 的无符号值相乘。这导致长度为 200 的结果(参见 numeric_std 包!)。您可以按以下方式解决您的问题:

entity main is
port(
input:in unsigned(99 downto 0);
clk:in std_logic;
output:out unsigned(199 downto 0)
);
end main;

architecture Behavioral of main is

begin
process(clk) 
    variable x:unsigned(99 downto 0); 
    variable x_res:unsigned(199 downto 0); 
begin 
    if(clk'event and clk='1') then 
        x:=(input); 
        x_res:=(x*x); 
        output<=x_res; 
    end if; 
end process; 
end Behavioral;
于 2013-03-15T08:26:32.153 回答