Search code examples
processintegervhdl

VHDL: Integer has a different behavior than expected


I'm developing a project in VHDL with a ZedBoard Zynq Evaluation Board. I wrote the following process, but I've notice that "stalloLoad" become '1' not when rd_sig = "00110", but at the next clock edge. Can someone explain me?

Thank you all!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Inst_decoder is
Port ( 
   clk: in std_logic := '0'; 
   inst: in std_logic_vector(31 downto 0) := (others => '0');
   rd: out std_logic_vector(4 downto 0);
 );
 end Inst_decoder;

architecture Behavioral of Inst_decoder is

signal istruzione: std_logic_vector(31 downto 0) := (others => '0');
signal stallo_sig: std_logic := '0';
signal contatoreLoad: integer := 0;
signal rd_sig: std_logic_vector(4 downto 0) := (others => '0');  

begin
process(clk) begin
if(rising_edge(clk)) then
istruzione <= inst;

stalloLoad <= '0'; --default
if(contatoreLoad > 0) then contatoreLoad <= contatoreLoad + 1;  end if;
if(contatoreLoad = 4) then
    contatoreLoad <= 0;
    stalloLoad <= '0';
    regLoad <= (others => '0');
end if;

if(contatoreLoad = 0) then
    codop <= inst(6 downto 0);
    rd_sig <= inst(11 downto 7);
    rs1_sig <= inst(19 downto 15);
    rs2_sig <= inst(24 downto 20);
    codop <= codop_sig;
    rd <= rd_sig;
    rs1 <= rs1_sig;
    rs2 <= rs2_sig;
            

    if(rd_sig = "00110") then
        contatoreLoad <= 1;
    end if;
end if; --if( stalli = 0)



if(contatoreLoad > 0) then
        istruzione <= (others => '0');
        rd <= (others => '0');
        stalloLoad <= '1';
  end if;    
end if; 

end process;
end Behavioral; 

Solution

  • From a simulation point of view (which mimics what happens in hardware) signals are sampled at the rising edge of your clock, then combinational logic is executed, and you see the new values updated at the next rising edge.

    What happens in your design is the following:

    enter image description here

    If you do not want this kind of latency you have to make 'stalloLoad' a combinational signal, and not a register, but this might cause trouble in other parts of your device.

    An example would be:

    process (clk) ..
    endprocess
    
    stalloLoad <= '1' when contatoreLoad > 0 else '0';
    

    However you should carefully think about the implications of this change for the rest of your desing.