as far as I know, always @* block is used in combinational circuit, and
the logic inside the always @* are sequentially executed regardless of the clock (asynchronous).
However, it seems that the logic inside always @* block in the below code
works synchronously according to the rising edge of the clock.
module univ_bin_counter
#(
parameter N = 8
)
(
input wire clk, reset,
input wire syn_clr, load, en, up,
input wire [N-1:0] d,
output wire max_tick, min_tick,
output wire [N-1:0] q
);
//signal declaration
reg [N-1:0] r_reg, r_next;
//body
always @(posedge clk, posedge reset)
if (reset)
r_reg <= 0;
else
r_reg <= r_next;
//next statement
always @*
if (syn_clr)
r_next = 0;
else if (load)
r_next = d;
else if (en && up)
r_next = r_reg + 1;
else if (en && ~up)
r_next = r_reg - 1;
else
r_next = r_reg;
//output statement
assign q = r_reg;
assign max_tick = (r_reg == {N{1'b1}});
assign min_tick = (r_reg == 0);
endmodule
Before I run the simulation, I expected that the syn_clr works asynchronously but it works synchronously.
Although the syn_clr is set at 90ns, the data q[2:0] becomes zero at the next rising edge of the clk. Although the syn_clr is set at 90ns, the data q[2:0] becomes zero at the next rising edge of the clk.
If my understanding is right, it should be located in the above
always @(posedge clk, posedge reset)
block instaed of always @* block.
Could you explain what makes the always@* block executed synchronously?
1 Answer 1
The always @*
statement executes asynchrounously. It is equivalent to writing the code below:
always begin
// wait for one of these signals to change
@(syn_clr or load or up or en or r_reg)
if (syn_clr)
r_next = 0;
else if (load)
r_next = d;
else if (en && up)
r_next = r_reg + 1;
else if (en && ~up)
r_next = r_reg - 1;
else
r_next = r_reg;
end
If you look at the value of r_next
, you will see that it gets evaluated after any change in the listed signals. It may be that all those signals are changing on a clock edge as well, so you don't see the difference.