简体   繁体   中英

Vhdl code acting weird (small code , where variable keeps its value and doesnt reset)

Here is the code:

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;

first problem is that x although a variable and should reset each time process is run it doesn't and saves its value! and I have seen it step by step in simulation. 2nd problem is although input is fixed to this entity and doesn't change by each clk process x either is x * input( correct answer) or 0( wrong answer) by the time my clock stops ticking it stops at 0 answers, if I decrease clock a little it may stop at correct answer (which is input x) my problem is why input x is not fixed if input and x are fixed, 2nd is why doesn't x resets when process is called again(from its sensitivity list). here is test code:


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;

///

Notice that at beginning of test the process is run several times without inserting input value, in this case I don't care about results, I am talking when input is inserted that this problem occurs.

The first thing to understand is that you never call a process!

A process is only started once - and so the variable is only initialised once.

It runs to completion and sleeps - the next clock event wakes it up and it executes from the beginning to completion in each clock cycle.

It may help to think of a process as being like a C main program with an event loop; it sleeps until the event happens, and the variable you have declared is a global variable (or "static" variable - it keeps its last value).

If you want the effect of a C function or procedure ( cough , void function) write a VHDL function or procedure; the local variables in these will be re-initialised each time you call them within the process.

So after 1 clock cycle you see x * input , after several clock cycles you see the least significant 100 bits of x * input * input * input ... * input which, thanks to multiplication word growth, will eventually all be 0.

If all you want to do is multiply each new input by the initial value of X, then you would be better to declare X a constant, and simply write:

process(clk)
constant x:unsigned(99 downto 0):=X"27c8a94a6fb72a00000000000";
begin
   if rising_edge(clk) then
      output <= x * input;
   end if;
end process;

the problem is, that you multiply 2 unsigned values of length 100. this leads to a result of length 200 (see numeric_std package!). you can solve your issue as follows:

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM