Search code examples
variablesvhdlunsignedfpgamultiplication

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 inputx 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.


Solution

  • 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;