When to use non-blocking (sequential) in Verilog - Time & Space Complexity
We want to understand how the time it takes to run sequential code with non-blocking assignments grows as the input size changes.
How does the number of steps change when we use non-blocking assignments in sequential logic?
Analyze the time complexity of the following Verilog sequential block using non-blocking assignments.
always @(posedge clk) begin
for (integer i = 0; i < N; i++) begin
reg_array[i] <= input_array[i];
end
end
This code copies values from one array to another on each clock cycle using non-blocking assignments.
Look for loops or repeated actions inside the sequential block.
- Primary operation: The for-loop that copies each element from input_array to reg_array.
- How many times: The loop runs N times every clock cycle.
Each clock cycle, the number of copy operations grows with N.
| Input Size (N) | Approx. Operations per cycle |
|---|---|
| 10 | 10 copies |
| 100 | 100 copies |
| 1000 | 1000 copies |
Pattern observation: The work grows directly with the size of the array. Double the array size, double the operations.
Time Complexity: O(N)
This means the time to complete the copying grows linearly with the number of elements.
[X] Wrong: "Non-blocking assignments run all at once instantly, so time does not grow with N."
[OK] Correct: Even though non-blocking assignments update registers simultaneously at the clock edge, the hardware still needs to handle each element, so the total work grows with the number of elements.
Understanding how sequential blocks with non-blocking assignments scale helps you design efficient hardware and explain your design choices clearly.
What if we replaced the for-loop with parallel assignments for each element? How would the time complexity change?