2
\$\begingroup\$

I have started learning Verilog and I apologize for the problematic coding.

If there's a repeat statement in "always@(*)" block, and after the repetition, the variable in the sensitivity list is same, would always@() be executed again? For example:

module test( input a);
always@(*) 
repeat (2) 
begin
    a = ~a; 
end
endmodule

After even cycles of repetitions, a will retain it's original value, so will the always block be executed?

If "always" depends on a variable a, and we have n number of repetitions in the always block for a = ~a. After even number of repetition a will be same. Will "always" be executed again as there's no change in the sensitivity list?

\$\endgroup\$
0

2 Answers 2

3
\$\begingroup\$

Depending on what the rest of your code looks like, there is a good chance that the always block was never triggered. If there was no change in a outside that block, then the block was never triggered, and the repeat block was never executed. That is one reason why you observed that a retained its original value.

Your code does not follow recommended Verilog coding style (for either design or testbench). In general, you should not "read from" and "write to" the same variable within a combinational always block like yours. You can easily end up with undesirable simulation race conditions. There are much better ways to repeatedly invert a signal. It depends upon what you are trying to achieve.


I wrote the answer above before I realized you posted a complete module. The module line was hidden from plain view until I edited the code block in the question. There is a syntax error in your code because it is illegal to make an assignment to an input port from within the module body. Regardless, my answer is still valid.

\$\endgroup\$
2
  • \$\begingroup\$ Yup, assigning value to an input in design code is wrong, but we do that in testbench file right ? , to assign initial values. BTW I wasn't trying to invert a signal though. I just wanted to know say there are 2 statements in always that execute in a way that first one changes the variable and second reverts it to original value. So overall variables hasn't changed and I wanted to know if "always" will run again. always@(a, b, c) // a is 0 in initially (declared in Testbench) repeat (2) ....some logic making a = 1 ....some logic making a = 0 end how many changes will "$monitor" show ? \$\endgroup\$ Commented May 29, 2023 at 12:11
  • \$\begingroup\$ @ItachiUchiha: Yes, you drive a module instance input from the testbench. If you want to know how many monitor will show, run a simulation. \$\endgroup\$
    – toolic
    Commented May 29, 2023 at 13:15
1
\$\begingroup\$

I think there are some general misconceptions about the execution semantics of an always block and the concept of a sensitivity list

The always construct instantiates a permanent procedural process. That process is either executing procedural statements, or suspended/blocked waiting for something to happen using an event control (e.g. a change on a signal or a delay to pass).

Typical RTL coding styles dictate a single event control as the first construct of the process, but the language allows many event controls anywhere within the process. Note that the language does not require any event controls, but without at least one, it would get stuck in an infinite loop at time 0.

The @(*) event control is a shortcut used when modeling combinatorial logic. The compiler automatically creates an event control list with all the signals used in that the process, based on the procedural block of code that follows it. The only exception is variables being written to, which are not added.

always @(*) begin // waits for a change on b, c, or e
    a = b + c;
    d = a + e;
end

Is the same as writing

always begin
    @(b or c or e) // variables a and d are not added to the list
    a = b + c;
    d = a + e;
end

The compiler does not look at behavior of the code when creating the list, just which signals have references.

Another thing to consider is that event controls are executable procedural constructs. They must execute first before the event happens If you add delays to the process

always @(*) begin // waits for a change on b, c, or e
    #5 a = b + c;
    #5 d = a + e;
end

Assume b first changes at time 10. The assignment to a happen at time 15 and the assignment to d happens at time 20. It is not until time 20 that the process waits for another change on b, c, or e. If b changed again at time 19, that change event will be missed.

\$\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.