i read an article about blocking assignment. module fbosc1 (y1, y2, clk, rst); output y1, y2; input clk, rst; reg y1, y2; always @(posedge clk or posedge rst) if (rst) y1 = 0; // reset else y1 = y2; always @(posedge clk or posedge rst) if (rst) y2 = 1; // preset else y2 = y1; endmodule Case1 If the first always block executes first after a reset, both y1 and y2 will take on the value of 1. Case2 If the second always block executes first after a reset, both y1 and y2 will take on the value 0. Question: 1. How is the flow for above case in terms of always block and blocking assignment? 2. if reset = 1, y1=0 and y2=1, isn't it? i don understand the explaination above. So, Try to explain in details. Thanks a lot
>always @(posedge clk or posedge rst) >if (rst) y1 = 0; // reset >else y1 = y2; > >always @(posedge clk or posedge rst) >if (rst) y2 = 1; // preset >else y2 = y1; hi, you will only have a problem if your asynchronous reset violates the setup/hold time of the flip-flops. Then the output of y1/y2 is unpredictable. If you change the reset to a synchronous type, it's much easier and clear what will happen. And it get's even more clear when you write this code into one single process. Or am I completely wrong? :o)
Something to read on blocking vs. nonblocking: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf On the other hand: Why not try making your homework yourself?
The problem stated above is the example i grab from that article. I don't understand the explaination. So, i ask in forum. Thanks
1: "According to the IEEE Verilog Standard, the two always blocks can be scheduled in any order. If the first always block executes first after a reset, both y1 and y2 will take on the value of 1. If the second always block executes first after a reset, both y1 and y2 will take on the value 0. This clearly represents a Verilog race condition." (Cummings) Simulation of HDL runs in time steps. Time steps are triggered by events, such as posedge clk or posedge rst in this case. Within a time step, all your code is evaluated. If the evaluation of the code generates a changed status of any RHS statement, all code is evaluated again with the new RHS value. This is done until there are no RHS changes, then the simulation time is advanced to the next event. Blocking assingments propagate the value instantly, i.e. within a timestep. So once the simulator arrives at the second process, the input is changed already. Both processes are scheduled to run on the same simulator time step (the step where "posedge clk"). Now let's consider the first process being run first: y1 = y2 (which is 1 at first posedge clk after release of rst) Next step for the sim would be to evaluate the second process (still, time in the simulator has not advanced!) y2 = y1 (which is now, thanks to blocking assignment already changed to 1) As the simulator does not see any changes on the RHS assignments to y1 and y2 anymore, the timestep is considered done and time advances to the next event. Same goes if the second process runs first: y2 = y1 (which is 0 after rst) Now again thanks to blocking assignments, y2 is already changed to 0: y1 = y2 In this case you end up with both y1 and y2 being 0. So as a bottomline: The result clearly depends on which process is evaluated first (in a naturally sequential simulation of the HDL). As it is not defined in the verilog standard which one is to be evaluated first, the fastest one wins. And that's called a race condition. 2: While rst you don't have a problem. y1 and y2 are perfectly defined. Problems start once you release rst. N.B.: If you want to synthesise that example to hardware, the hardware would behave like the designer probably intended it to do. In the simulator it would however not show the same behaviour as in hardware. I think the easiest conclusion would be: Avoid using blocking assignments until you really know what you are doing. For my part, I am only using non-blocking assignments simply because it's less error-prone.
I think all the replies are missing the point; this example and explanation are not intended to be synthesizable RTL but to demonstrate blocking statements. As Gast states above, the simulation is done in time slots. A blocking statement says assign the right hand value to the left hand side and don't do anything else until the left hand variable has been updated. Thus anything that uses the left hand variable subsequently will have the new value after. When reset is asserted, both elements are preset; y1=0, y2=1. The only time they will change will be after reset is deasserted, and on the rising edge of the clock. At that point, there are two cases as described. In case one the statment y1 = y2 is executed first. y1 takes the reset value of y2, 1 then the block is released and the other statement executes, y2=y1. Since y1 has been updated y2 will take this new y1 value, i.e. 1. If they were non-blocking statements, the both y1 and y2 would take on the old value of the other; i y1 would = 1 (reset value of y2) and y2 would be 0 (reset value of y1). The effect would be y1 and y2 would always be opposite logic levels and they would both toggle on each clock.