Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Adding 2 32-bit numbers and storing the result in a 33 bit register

Hello,

I need to add two 32-bit unsigned numbers and need to store in a 33 bit register in VHDL. Is it possible to do so. If so, then please help me to do so. Thanks in advance

19 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Can you please give an example with a while loop doing so, because I don't need any variable to do this

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Ok, got it. How to write some randomized inputs for this testbench a kind of a loop I mean

    --- Quote End ---

    This a prbs(25 downto 1):

    
    process(reset, clk)
    begin
    if(reset = '1')then
       shift_reg <= '0'    & x"00F0F1";
    elsif(rising_edge(clk))then
           shift_reg(1) <= shift_reg(25) xor shift_reg(22);
          shift_reg(25 downto 2) <= shift_reg(24 downto 1); 
    end if;
    end process;

    then:

    assign fcw_i with some 32 bits (mix as you like) and assign mod_i 24 bits (choose your favourite bits) from shift_reg
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    This a prbs(25 downto 1):

    
    process(reset, clk)
    begin
    if(reset = '1')then
       shift_reg <= '0'    & x"00F0F1";
    elsif(rising_edge(clk))then
           shift_reg(1) <= shift_reg(25) xor shift_reg(22);
          shift_reg(25 downto 2) <= shift_reg(24 downto 1); 
    end if;
    end process;

    then:

    assign fcw_i with some 32 bits (mix as you like) and assign mod_i 24 bits (choose your favourite bits) from shift_reg

    --- Quote End ---

    Thats more of a logical approach. If you want a more programatical approach, VHDL has a built in random number generator:

    
    use ieee.math_real.all; -- for the uniform procedure;
    signal input : unsigned(7 downto 0);
    process
      variable seed1, seed2 : positive := 632165687; -- pick any positive value as a seed
      variable rand : real;
    begin
      wait until rising_edge(clk);
      
      uniform(seed1, seed2, rand);
      ip <= to_unsigned( integer((rand * real(2**input'length)), input'length);  --makes random integer from 0 to 255
    end process;
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks,

    I have written the test bench accordingly and it looks like this:

    p_rand_gen: process
      variable s1_v, s2_v: positive;
      variable rand_v: real;
      variable fcw_v : real := 40000.0;
      variable mod_v : real := 1600.0;
      begin	
        
    	 wait for 25 ns;
    	 
    	 uniform(s1_v,s2_v,rand_v);
    	 rand_mod_s <= integer (rand_v*fcw_v);
        rand_fcw_s <= integer(rand_v *mod_v);
         
    	 wait for 10 ns;
        
       end process; 
    	
      --stimulus  
      p_stim: process
      begin
         
        wait for 10 ns;
        reset_n_i <= '1';
    	 
        wait for  15 ns;
        enable_i <= '1';
    	 
        	 
    	 fcw_i <= std_logic_vector(to_unsigned(rand_fcw_s , 32));
        mod_i <= std_logic_vector(to_unsigned(rand_mod_s, 24));
    	 
        wait for 10 ms; 
        reset_n_i <= '0';
     
        wait for 1 ms;
        reset_n_i <= '1';
        wait for 1 ms;
        enable_i <= '0';
        
        wait for 1 ms;
        enable_i <= '1';
        		 
        wait for 10 ms;
    	 
        assert false report " End of the simulation" severity Failure;
      end process;
        
      delay_rst_s <= reset_n_i after 1 ns;
      
      p_fcw_chk: process(delay_rst_s, clk_128meg_i)
      begin
        if (delay_rst_s = '0') then
          assert fcw_mod_o = "000000000000000000000000000000000" report "Output is not set to default value when reset_n_i is 0" severity error;
        elsif (clk_128meg_i'event and clk_128meg_i = '0') then
          if (enable_i = '1') then
            
              new_mod_s <= std_logic_vector("000000" & mod_i & "000");
              old_fcw_s <= std_logic_vector("0" & fcw_i);
              assert fcw_mod_o = std_logic_vector(unsigned(old_fcw_s) + unsigned(new_mod_s)) report "Wrong output" severity error;
          else
              assert fcw_mod_o = "000000000000000000000000000000000" report "Output is not set to default value when enable_i is 0" severity error;
          end if;
       end if;
        
      end process;
       

    What I need to do is that, when the variables rand_mod_v and rand_fcw_v are updated, they should reflect the change at once in fcw_i and mod_i which I have written in the "stimuli: process", But its not getting updated. I don't know why. Thanks in advance
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    @Tricky,

    Thanks a lot. I have posted the problem previously. What I need to do is I need to update the values of fcw_i and mod_i after every 10 ns (ie, whenever the values of rand_mod_v and rand_fcw_v are updated). Please help me out to solve this problem. I am getting really frustrated
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    What I need to do is that, when the variables rand_mod_v and rand_fcw_v are updated, they should reflect the change at once in fcw_i and mod_i which I have written in the "stimuli: process", But its not getting updated. I don't know why. Thanks in advance

    --- Quote End ---

    Thats because you have only assigned them once in the p_stim process, so they will have whatever value is on rand_fcw_s and rand_mod_s. Because both processes are meant to execute code at exactly the same time, they will take the initial values of the rand signals.

    You need a loop in your p_stim process to update the signals. why not just ditch the p_rand_gen process altogether and ut the random generation in the p_stim process?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    When I try to join the p_rand_num process along with p_stim process, then the values are not updated. Can you help me how to write a loop within the p_stim process to perform this operation. Please help me

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    
    --stimulus  
      p_stim: process
        variable s1_v, s2_v: positive;
        variable rand_v: real;
        variable fcw_v : real := 40000.0; -- Why are these variables and not constants?
        variable mod_v : real := 1600.0;  -- Why are these variables and not constants?
      begin
         
        wait for 10 ns;
        reset_n_i <= '1';
    	 
        wait for  15 ns;
        enable_i <= '1';
    	 
        for i in 1 to N_INPUTS loop
          uniform(s1_v,s2_v,rand_v);
          rand_fcw_s <= integer(rand_v*mod_v);
          rand_mod_s <= integer(rand_v*fcw_v);
          
          fcw_i <= std_logic_vector(to_unsigned(rand_v*mod_v, 32));
          mod_i <= std_logic_vector(to_unsigned(rand_v*fcw_v, 24));
          wait until rising_edge(clk) -- much better to synchronise to the clock rather than waiting for a time period
        end loop;
       
        wait for 10 ms; 
        reset_n_i <= '0';
     
        wait for 1 ms;
        reset_n_i <= '1';
        wait for 1 ms;
        enable_i <= '0';
        
        wait for 1 ms;
        enable_i <= '1';
        		 
        wait for 10 ms;
    	 
        assert false report " End of the simulation" severity Failure;
      end process;
    

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks Tricky,

    That came out pretty much well. Bit relaxed right now.