I have a counter called lastelem_reg. At the rising edge of each clock, it should check whether another signal enqueue is HIGH. If it is, then lastelem_reg will be incremented by 1 in the next clock, otherwise it continues to hold its old value. This seems like a very simple problem, but I'm not getting the intended behavior. Here's the VHDL code:
process(clk,reset)
begin
if (reset='1') then
lastelem_reg <= (others=>'0');
elsif (rising_edge(clk)) then
lastelem_reg <= lastelem_next;
end if;
end process;
process(lastelem_reg)
begin
if (enqueue = '1') then
lastelem_next <= lastelem_reg + 1;
else
lastelem_next <= lastelem_reg;
end if;
end process;
Simulating the above code, results in the waveform shown below. We see that lastelem_reg never gets updated.
So, I thought let's add enqueue to the sensitivity list of the second process and see what we get. The waveform is shown below. We see two things happening here that not supposed to happen. First, the lastelem_next signal changes twice every clock cycle, which shouldn't be happening. Second, the lastelem_reg is updating 1 clock before it should. For example, at 10ns, when the first enqueue signal comes, lastelem_reg should be 0, but here it is 1.
enqueue
in the second sensitivity list is correct. There's nothing wrong withlastelem_next
changing like that, andlastelem_reg
is updating on every clock, becauseenqueue
is asserted on every clock. \$\endgroup\$enqueue
is high at that clock edge, so it increments. If you want something different, you need to drive the inputs differently. Or if you want it to increment TO zero, then you need to reset it to all-ones (effectively -1). \$\endgroup\$lastelem_reg
to all ones (... (others => '1')
). Then the firstenqueue
operation will increment it to zero. On the other hand, if you don't want it to increment at all on that first clock edge, you must not assertenqueue
there. \$\endgroup\$