Although the "@(...)" structure is mostly seen in combination with the 'always' it is by no means the only place. It can also be used to wait for an event. This is normally done in test benches.
This is some code from one of my test benches:
@(posedge clk) ;
for (r=0; r<32; r=r+1)
begin
radrs <= r%16;
read <= 1'b1;
@(posedge clk) ;
radrs <= 'hx;
read <= 1'b0;
@(posedge clk) ;
while (ready==1'b0)
@(posedge clk);
end
Coming back to your code (I removed the comment and reformatted):
always@(posedge a)
@(posedge a) b = a;
Thus you have an always block which is triggered by a positive edge on 'a'.
After the positive edge it waits for another positive edge on 'a' and then assigned b to a. In this case the value of 'b' will always be one after the second rising edge on 'a' and then never change.
What is more a problem is your test bench. You assign values to 'a' with no time delay. In Verilog this means there is a delta delay between them (A simulation time delay with no physical delay). If you want to see the effect of your code use this:
initial
begin
a = 0;
#10 a = 1;
#10 a=0;
#10 a=1;
end

@is an event control statement. Wheneverposedgeofahas arrived, at that time, the@must have been reached and waiting on event. If you uncomment this code, then it will wait for two positive edges ofabefore assigning value tob. It is a race condition since theinitialblock may execute first and then the second@arrives. So,bis never assigned any value. - sharvil111