steveicarus / iverilog

Icarus Verilog
https://steveicarus.github.io/iverilog/
GNU General Public License v2.0
2.85k stars 529 forks source link

Async reset vs Sync reset #147

Closed red0bear closed 6 years ago

red0bear commented 7 years ago

Hello everybody !!!! How are you guys ?

People i get a issue here. I' m working with SpaceWire RX these days and i faced a little problem.

i have two counter using posedge and negedge from clock recovery. When i use registers with async reset they assume values on edge clock instead after edge clock. So i would like to know this behavior is correct, if using a register with async reset is right it acts like a wire. I made an example, please checkout.

Thank you guys ;-).

EXAMPLE COUNTERS

caryr commented 6 years ago

Your test bench has issues. Specifically you are aligning the reset with the positive edge of the clock and that same clock is begin used to trigger the counters. This creates a race between the reset and clock going to the always blocks. If you delay the reset in the VPI code by using an inertial delay value of 100 you will see that the async resets and sync resets work exactly as expected.

Unless I am missing something this is not an issue with Icarus. I will leave this open so you can comment. I expect based on how long ago this was posted you have likely already figured out your issue and fixed it. In general it is best to use more conventional resources if you have questions about Verilog and reserve this issue tracker for things that you are fairly certain Icarus is doing incorrectly.

red0bear commented 6 years ago

Hi there !!!

Well Mr. caryr ..... works exactly is a hard question to me because i don't have gate level and i was trying to mix combinational creating a clock , but sometimes in some versions in icarus vvp just broken or freeze. i tried to figured sometime and after many tries i decided change again many parts of source code and problem stopped. There is a relation with counters in my old source code .... but i didn't find it.

caryr commented 6 years ago

Icarus is likely freezing because of your code and not because it has a defect. Understanding how events are handled in a Verilog simulator and the non-determinism that can result is an important skill a logic designer needs to acquire. The Verilog standard clearly specifies this.

For example the code you posted has the asynchronous reset release aligned to the positive edge of the clock. In a real gate this would give non-determinism regarding the reset still being active and the clock sampling a new value. Because of delay variations you may not even get the same behaviour over time, unit, etc. Icarus has a flag to enable debugging these lock up issues by adding lines in the VVP code to print the file/line information as the various lines of code are executed. This generates a huge amount of output, but when things lock up it shows which pieces of code are interacting with each other and are causing time to not advance (-pfileline=1).

I will suggest you read the following paper to get more understanding regarding resets: http://www.sunburst-design.com/papers/CummingsSNUG2003Boston_Resets.pdf. The primary thing to remember is you need to satisfy setup/hold requirements for a synchronous reset and for an asynchronous reset you want to ideally release it on the opposite edge of the clock relative to the sampling edge. Fundamentally you need to satisfy the recover and removal of the reset deassertion relative to the clock.

red0bear commented 6 years ago

Thank you to take time to explain, like a said i take here just a example counter. The real where i get problems when i try make changes is this : https://github.com/GLADICOS/SPACEWIRESYSTEMC

At least when i tested on Cadence it works .... so i could not figure out whats wrong. It aim to obey ASIC rules, but im sure there a lot of problems yet. I'm using Altera software to make syntheses but still unstable.

Well i will take a good look in this paper could it show me something good to correct in the project.

caryr commented 6 years ago

Just because one tool gives expected operation does not indicate that the code/design is correct. A good design will work on any simulator. Think of the different simulators as different versions of your design where each processes the logic transitions at a single time step slightly different (e.g. are events at a specific time step processes as FIFO, LIFO, random, something different). The reality is a real circuit will often run all this in parallel; while the simulators will run things serially and in some order. This difference creates a false sense of security that the design is correct when in fact it is only correct because of the subtleties of a given simulator. A robust design would not be sensitive to any event order differences.

In the code you provided I see a lack of understanding regarding these issues. This is very common for people new to Verilog and occasionally for more senior people as well. By taking some time to study and think about how logic simulators and real circuits work I am sure you will gain insight into why your circuits were not functioning correctly.

If you have no objection I will close this item since the issues you are experiencing do not appear to be bugs in Icarus.

red0bear commented 6 years ago

Sure you can close it.