Search code examples
vhdlbit-shiftquartus

Shift Right (srl) going wrong on VHDL Quartus II


I'm trying to make a 8-bit Sequential Multiplier on Quartus II. I did all the simulations of all blocks, but one is showing error on the VWF simulation. The sum_reg block it's doing a infinite shift in a very small time interval.

enter image description here

In the "dark blue" part of waveform simulation, on o_DOUT, it's when the shift gones infinite until the MSB goes to the LSB. The image below shows what happens in the dark blue part of the simulation:

enter image description here

Someone know what's happen?

Below the code:

Sum register(where the simulation goes wrong):

 library IEEE;
 use IEEE.std_logic_1164.all;
 use IEEE.numeric_std.all;

 entity sum_register is 
 port (
     i_DIN   : in UNSIGNED(8 DOWNTO 0);
     i_LOAD  : in STD_LOGIC;
     i_CLEAR : in STD_LOGIC;
     i_SHIFT : in STD_LOGIC;
     o_DOUT  : buffer UNSIGNED(15 downto 0)
 );
 end sum_register;

 architecture arch_1 of sum_register is 
 begin 
     process(i_CLEAR,i_LOAD,i_SHIFT, i_DIN)
     begin
        IF (i_CLEAR = '1') THEN
            o_DOUT <= "0000000000000000";
        ELSIF (i_LOAD = '1') THEN
            o_DOUT(15 downto 7) <= i_DIN;
        ELSIF (i_SHIFT = '1') THEN
             o_DOUT <= o_DOUT SRL 1;
        END IF;
      end process;
end arch_1;

Solution

  • You need to use a clock signal in the circuit to make this synchronous, you will need an input in your entity like this:

    i_CLOCK : in STD_ULOGIC;
    

    After this you will need to make your process sensitivy to the clock:

    process(i_CLOCK)
    

    And your architecture will change to this:

     architecture arch_1 of sum_register is
      SIGNAL r_DOUT : unsigned(15 downto 0);
     begin
         process(i_CLOCK)
         begin
         IF rising_edge(i_CLOCK) THEN
            IF (i_CLEAR = '1') THEN
                r_DOUT <= "0000000000000000";
            ELSIF (i_LOAD = '1') THEN
                r_DOUT(15 downto 8) <= i_DIN;
            ELSIF (i_SHIFT = '1') THEN
                  r_DOUT <= r_DOUT SRL 1;
            END IF;
          END IF;
          end process;
          o_DOUT <= r_DOUT;
    end arch_1;
    

    With this architecture you will need a unsigned signal to make atribution for your output o_DOUT, with this you can change your o_DOUT output to output type again (not buffer).

    NOTE: The clock signal needs to be the same for all blocks!