1
\$\begingroup\$

I've always been told that a signal updates its values after a wait statement, or after a rising edge if we have for example

if rising_edge(clk) then

but in this testbench, after the first wait statement and giving values Rst, Load, and Data, which are signals, it updates those signals instantly, if I use ModelSim, it doesn't wait after the second wait statement to update those signals.

 readVec: PROCESS
VARIABLE    VectorLine:     LINE;
VARIABLE    VectorValid:    BOOLEAN;
VARIABLE    vRst:       STD_LOGIC;
VARIABLE    vLoad:      STD_LOGIC;
VARIABLE    vData:         STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE    vQ:            STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE   space:       CHARACTER;
BEGIN
WHILE NOT ENDFILE (vectorFile) LOOP
  readline(vectorFile, VectorLine); -- put file data into line
  read(VectorLine, vRst, good => VectorValid);
  NEXT WHEN NOT VectorValid;
  read(VectorLine, space);
  read(VectorLine, vLoad);
  read(VectorLine, space);
  read(VectorLine, vData);
  read(VectorLine, space);
  read(VectorLine, vQ);
  WAIT FOR ClkPeriod/4;
   Rst <= vRst;
   Load <= vLoad;
  Data <= vData;
  Qexpected <= vQ;
  WAIT FOR (ClkPeriod/4) * 3;
  END LOOP;
 ASSERT FALSE
  REPORT "Simulation complete"
  SEVERITY NOTE;
  WAIT;
END PROCESS;  
\$\endgroup\$
2
  • 1
    \$\begingroup\$ That isn't what "wait" means. Within a process, statements are simulated sequentially. So the simulator waits at the first wait, then updates the signals, and then it waits at the second wait. If you don't want the signals to update until after that, then move the assignment statements after the second wait. \$\endgroup\$
    – Dave Tweed
    Jan 19, 2022 at 22:22
  • 1
    \$\begingroup\$ It updates its values when the process suspends (whether at "end process" or it reaches a Wait (in this case the second Wait) ... NOT when that second Wait expires. \$\endgroup\$
    – user16324
    Jan 19, 2022 at 23:11

1 Answer 1

1
\$\begingroup\$

I've always been told that a signal updates its values after a wait statement, or after a rising edge if we have for example 'if rising_edge(clk) then'

You've been misinformed somewhat. In VHDL, a signal updates its value:

  • on a wait statement (not after it)
  • at the end of a process

'On a wait statement' means 'upon starting the wait statement'.

A process that has a sensitivity list is said to be sensitive to the signal(s) in that list. The process has the same behaviour as a process with no sensitivity list but instead having all of the list signals in a 'wait on' statement - which must be final statement in the process.

So the following are logically identical:

  p: process(RST, CLK) is
  begin
    if (RST = '1') then
      a  <=  '0';
    elsif rising_edge(CLK) then
      a  <=  b;
    end if;
  end process p;

  p: process is
  begin
    if (RST = '1') then
      a  <=  '0';
    elsif rising_edge(CLK) then
      a  <=  b;
    end if;
    wait on RST, CLK;
  end process p;

From this, a signal update does not happen on a rising edge because the rising_edge function is 'special' in some way. rising_edge simply executed when the process is executed, which happens if the process it's in is sensitive to the signal rising_edge tests. Both are usually a clock.

In your example shown, the signals will be updated after the first 1/4 of your clock period. Most often, it would be written instead as:

  ...
  read(VectorLine, vQ);
  Rst  <= vRst;
  Load <= vLoad;
  Data <= vData;
  Qexpected <= vQ;
  wait for ClkPeriod;
  ...

This updates the signals at the start of each clock period, the same as the actual design logic processes that your testbench is testing will do.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.