Uninitialized reg in simulation vs. synthesis - Page 1
Forum section: electronics / general

author: hinxx
author_rank: Contributor
timestamp: August 06, 2020, 10:18:17 am
content: Complete n00b in Verilog asking a question here, so bear with me please. I have no prior experience in FPGAs/Verilog/VHDL, I do in C, though.I'm playing around with a FPGA board from Olimex,https://www.olimex.com/Products/FPGA/iCE40/,and have managed to put the blinking LEDs demo into the board ; and they blink.I'm trying to understand the demo code as seen herehttps://github.com/OLIMEX/iCE40HX1K-EVB/blob/master/demo/ice40hx1k-evb/example.v.For example, how the uninitialized reg:Code:reg[14:0]cntr;is never assigned a value of 15'b0, yet it is incremented in the always block:Code:cntr <= cntr + 15'd1;and appears to be starting from 0?!When I try to use iverilog and vvp to simulate the design the cntr is left at 15'bx, while on the hardware cntr clearly seems to take on a specific value at the start. I assume this value is 15'b0. Is this correct? Where does it come from? I assume this is done during the synthesis process, but fail to pin point down in which part.Information I managed to get so far is that in synthesis "x is ignored", at least the assignment (with some exceptions); have not found the answer about the initial value though, if not initialized explicitly. Is there a better explanation to get from somewhere? I would also be interested in a list of differences between the simulation and synthesis of the Verilog models (i.e. what can and can not be done in one vs the other).

author: tggzzz
author_rank: Super Contributor
timestamp: August 06, 2020, 11:44:36 am
content: Since I don't know the toolset and hardware you are using, this is a generic answer.Synthesis ought to create a netlist and components from the information in your design, no more no less.Simulation ought to show values that are unknown, except when and where definite values can be computed from the design and execution. For example an 8-stage shift register with the serial input tied low should start out with all outputs unknown. After each clock one more output will be low, until after 8 clocks they will all be low.Hardware will always power up in one state or another. The precise state will either be guaranteed in the datasheet, or random in the sense that you cannot rely on the state. Any given register will probably start in the same state every time - but you should not presume what that state will be.For example, a 3 bit counter might start as 0 or 1 or 6 or 7 etc. After 8 clocks it will again be 0 or 1 or 6 or 7. Nonetheless, the simulator ought to show the count as unknown for all time.

author: hinxx
author_rank: Contributor
timestamp: August 06, 2020, 12:52:43 pm
content: Quote from: tggzzz on August 06, 2020, 11:44:36 amIt is yosys, arachne-pnr, icepack based toolchain and the chip is Lattice iCE40HX1K. For simulation I use iVerilog and vvp along with GTKwave.Quote from: tggzzz on August 06, 2020, 11:44:36 amI think I can understand that. And it makes sense; I'm seeing this in vvp outputs and waves in GTKwave as well. Where I fall short in understanding is how does the chip manage to get out of the unknown value. I was thinking that the toolchain would set up some 'sane' defaults for the hardware in synthesis process, whereas for simulation designer has to explicitly perform the task of initialization.Quote from: tggzzz on August 06, 2020, 11:44:36 amDoes that mean that the iCE40HX1K chip once programmed will determine the startup (initial) values of the uninitialized regs.. in some startup sequence or similar?Quote from: tggzzz on August 06, 2020, 11:44:36 amYes, I've been seeing unknown for the cntr in question, when running simulation, and as far simulation goes I'm fine with it.

author: mfro
author_rank: Regular Contributor
timestamp: August 06, 2020, 01:07:42 pm
content: Quote from: hinxx on August 06, 2020, 12:52:43 pmThe chip itself does know a value. It doesn't know anything else than 0 or 1 (so, depending on your toolchain and hardware, it might be *any* value or even 0 as intended).Basically identical to using an unitialized variable in C. You won't do that there as well, don't you?

author: tggzzz
author_rank: Super Contributor
timestamp: August 06, 2020, 01:33:14 pm
content: Quote from: hinxx on August 06, 2020, 12:52:43 pmSee below. The hardware is always in a valid state. Exceptions: metastability and input signal integrity failures.QuoteNo.Only the designer can define what a "sane" value might be.QuoteRTFDSIf it doesn't say anything, you can't assume anything.Part of the art is reading what a data sheetdoessay. The other part is reading what it doesnotsay.In general it is good practice to explicitly force a device into a known state. That "reset" can be done whenever convenient and/or necessary.QuoteThat sounds as if the simulator presumes something about the hardware initialisation state. Is there any reason to believe that the hardware's behaviour will always match the presumption? Personally I would distrust asimulationwhere the outputsdon'tstart as "unknown" - until after the device has been reset.In a professional context, that would not pass a design review. Predictability and repeatability are very important.

author: asmi
author_rank: Super Contributor
timestamp: August 06, 2020, 02:06:13 pm
content: Some FPGAs do not support register initialization from bitstream, so unless you know for sure that your target device does support it, it's wise to include a startup reset code which will place your design in known initial state.

author: hinxx
author_rank: Contributor
timestamp: August 06, 2020, 03:32:06 pm
content: Thank you all!In short my cntr initial value could be anything at start. It would eventually wrap at 15'd24414. I guess the only side effect, in this case, might be reaching the wrapping point sooner in the first iteration, whereas for subsequent iterations it counts from 0 to 15'd24414.Takeaways:* do not assume what uninitialized bit value is - can be 0 or 1 depending on the toolchain output and/or hardware* implement init of the regs at reset time* try to extract the default state (if any) from datasheetIf I would like to see if my toolchain does it, does anyone know, how to look it up? In which phase could I see that?.. off to read some hardware datasheets ..

author: fourfathom
author_rank: Super Contributor
timestamp: August 06, 2020, 03:47:08 pm
content: With the Lattice FPGAs, the registers are physically initialized at startup, From this document (http://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/EH/HDLSynthesisCodingGuidelinesforLatticeFPGAs.ashx?document_id=4815):QuoteThe synthesis tools I've used for Lattice take this into account. I wouldn't depend on this if your design doesn't self-correct for a random state at startup.

author: tggzzz
author_rank: Super Contributor
timestamp: August 06, 2020, 04:21:39 pm
content: Quote from: hinxx on August 06, 2020, 03:32:06 pmGood to see a student that thinks, asks, listensIf you do rely on the default state, then document that very carefully. That will help someone else, or help you in a year's time, or help when moving the device to a different toolset.As an example of why only the designer can specify a sane initial value, consider an FSM implemented using the "one hot" design pattern. That's particularly relevnt for FPGAs, and each state is encoded as a different flip-flop output being active. Clearly not having any outputs active (or more than one active) is an invalid violation of the design pattern.

author: Bassman59
author_rank: Super Contributor
timestamp: August 06, 2020, 04:52:49 pm
content: This is the reason why all digital logic designs require a logic reset -- to get all of the registers into a known state.Some FPGAs, like Xilinx and Lattice, support an internal global reset (GSR) that is asserted after configuration. You determine the states to which the flip-flops are set or reset at that time by writing initializers in your code.In VHDL that's simply:signal foo := std_logic_vector(7 downto 0) := "10100110";where the:= "10100110"is the initializer.Sorry, I forget how to do this in Verilog.Other FPGA families, like MicroSemi ProASIC-3, require an explicit reset to come from somewhere. In this case, you can use one of those little reset supervisor chips which hold their output asserted for some time after power supplies are stable. You connect that to an input on your FPGA and you use it as a global asynchronous reset, and you then write your Verilog appropriately. In your @always block you add the reset signal on the sensitivity list and code the reset condition to set all signals to the desired reset state.(There are good arguments to be made about synchronizing an external reset, but let's leave that alone for now.)Anyway, reset is very important. The thing with the GSR initializer is that people forget that it's actually a reset.

author: BrianHG
author_rank: Super Contributor
timestamp: August 06, 2020, 05:18:37 pm
content: In verilog:reg [14:0] cntr = 15'd0 ; // 15'd0 initializes the power-up default to decimal 0.reg [14:0] cntr = 15'bxxxxxxxxxxxxxxx ; // 15'bx initializes the power-up default value to an undetermined state.This is useful in simulation because in the output waveform, you can track when that register was first assigned a value via actual code. So, if somewhere in the beginning of your functioning code, if you have a reset pulse somewhere in you simulation setting the reg to 0, but not at powerup, or if you forgot to assign a value of 0 to this variable during the reset itself, you can now see the mistake in your simulation.

author: hinxx
author_rank: Contributor
timestamp: August 08, 2020, 10:08:25 am
content: Again, I really appreciate the responses here. Thank you all!Quote from: fourfathom on August 06, 2020, 03:47:08 pmGSR would explain it. I have not seen the linked doc before as it did not appear in the list of docs under the iCE40HX1K part. The HX1 family doc mentions GSR as well, but I could not grasp the concept due to being flooded with this new terminology about the FPGAs.Quote from: fourfathom on August 06, 2020, 03:47:08 pmI do not quite understand the above statement. Are you saying that I should defer the initialization to a dedicated reset procedure (presumably handcrafted) just to be sure that it happens and does the right thing(r)?From what I've been hearing here, and reading some of the Lattice docs, I think one can drive perform the GSR from the HDL code. How is that done? In the suggested codeQuote from: Bassman59 on August 06, 2020, 04:52:49 pmI fail to understand what signal/wire/registerfoois actually driving. I'm not asking about the VHDL vs. Verilog syntax differences here, but how does the"10100110"actually perform GSR, if at all? Is"10100110"some kind of a magic value perhaps? OTOH, docs are also saying that several external pins can perform the GSR for my part.

author: tggzzz
author_rank: Super Contributor
timestamp: August 08, 2020, 10:21:09 am
content: Quote from: hinxx on August 08, 2020, 10:08:25 amThat is good practice.You remove all sorts of assumptions and misunderstandings.You can invoke it at any time in an operational system, e.g. if a watchdog times out or an FSM enters an invalid state.

author: NorthGuy
author_rank: Super Contributor
timestamp: August 08, 2020, 03:12:29 pm
content: Quote from: hinxx on August 08, 2020, 10:08:25 amReset and initialization are two different things. Initialization assigns the value when you design start. Reset is a signal (or many signals in a complex design) which assigns known values to registers when it is asserted. Initialization is free - these are just configuration bits which either can be 0 or 1 in your bitstream. Reset requires resources - at the very least the reset signal must be distributed through the fabric.Therefore, if you don't need reset, then use initalization - initialize everything as you want, don't do the reset. In simulation, you will see everything already initialized from the start.If you do need a reset, it is better to keep only one copy of everything. Otherwise, there may be differences in how your design behaves when it comes from reset compared to the behaviour after the start. Therefore, don't use initialization. Instead, start in reset, then release the reset when needed. This guarantees that your design always go through reset. Do not reset everything, only what you need - often most of the logic is "do not care" and there's no need to assign it at reset - this is just waste of resources. In simulation, if you spot something undefined, which you need initialized, add the corresponding assignment to reset.

author: tggzzz
author_rank: Super Contributor
timestamp: August 08, 2020, 03:19:28 pm
content: Quote from: NorthGuy on August 08, 2020, 03:12:29 pmIt is worth noting that a reset doesn't have to affectallregisters.Consider a pipelined design with 10 stages. It is sufficient if the reset only changes the first stage register, provided that you specify last state register isn't used/examined until after 10 clocks have occurred.

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 08, 2020, 03:33:24 pm
content: Long story short: as you clearly identified it, this is an uninitialized register. As such, any decent simulator will see it as "X" (unknown state).But synthesized on a given FPGA - it depends! Many FPGAs just reset all flip-flops right after configuration, so if not explicitely initialized, they are likely to start with a value of zero. When this is not the case, obviously on real hardware, any register WILL have a value, even if it's not zero, so the design per se can't be stuck (whereas in simulation, if a register is X, then incrementing it will have no visible effect (will keep being X until explicitely assigned a value.)Some FPGAs/vendor tools allow explicitely initializing registers/signals within the HDL code (as suggested above). This approach will work both in simulation and on many (but not all) FPGAs.Otherwise, the proper way of dealing with initialization would be to implement a reset state in your code.Then whether you *really* need to initialize a given register/signal depends on your design. It's not necessarily the case. At least not necessarily at a common "reset" event. You don't need to initialize a signal early if it's going to be used many clock periods after a "reset" for instance. You can assign it an initial value in some kind of FSM instead for instance. Or, in some cases you actually don't care about the initial value. Say you're using a counter to flash a LED or something - initializing the counter may not matter as you may not care about the very first "flash" period.But as I said first, if you don't initialize a given signal, you may still have simulation issues - so all in all, the common approach to this is - either you initialize it upon a "reset" state (asynchronous or synchronous), or initialize it at the declaration level - then it's likely to work on many FPGAs, and even if it doesn't (and as long as it doesn't matter), it will at least make the simulation work.

author: fourfathom
author_rank: Super Contributor
timestamp: August 08, 2020, 04:10:54 pm
content: Quote from: hinxx on August 08, 2020, 10:08:25 amThere are some good explanations above. Here are some additional thoughts on the subject:* You may want to simulate with a different toolchain, or target a different device, and the physical or simulated global reset or other initializer may be different. In this case having an explicit reset or initialization in your design will ensure predictable states.* If your design uses logic that would become stuck in in an improper state by, say, a cosmic ray hit or other Random Act of God, then even an initial reset will not protect you. You need to decode all illegal states and restore proper operation. I've seen this in design reviews where there are two counters that are initially synched and offset in a particular state and rely on this forever. The only way to correct a random error was to reset the entire system --not good. I made the engineer redesign it. I'm sure you can think of other designs that might be sensitive to this (one-hot circulating shift registers, etc.) Of course this issue is valid regardless of whatever form of initialization or reset you have.

author: radar_macgyver
author_rank: Frequent Contributor
timestamp: August 08, 2020, 08:08:25 pm
content: Xilinx recommends that you avoid the use of an async reset if possible, and try instead to use the GSR mechanism to ensure the registers are at a known value. This is because an async global reset net is by definition a high-fanout net, and will be difficult for the tools to meet timing. That said, I try to use an explicit async reset in all my designs, maybe because I'm oldschool?https://www.xilinx.com/support/documentation/white_papers/wp272.pdf

author: tggzzz
author_rank: Super Contributor
timestamp: August 08, 2020, 08:18:29 pm
content: Quote from: radar_macgyver on August 08, 2020, 08:08:25 pmThe other reason is that an async reset is, um, asynchronous. Hence there is the possibility that the releasing the reset won't meet a register's setup and hold times, which might lead to behaviour that depends on the device/temperature/phase of moon.There is a place for asynchronous logic, but those with a solid base in theory will know that it isextraordinarilydifficult to get correct - and even then "correctness" presumes that only one input changes at any one time (which is unrealistic except in synchronous logic!).So, keep async signals to an absolute minimum (i.e. inputs and clock-domain crossing logic), and use metastable-resistant design where theyhaveto be used.

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 08, 2020, 08:33:56 pm
content: Quote from: tggzzz on August 08, 2020, 08:18:29 pmThere's room for some debate here - and this has already been discussed a few times here, and a lot of times everywhere. But you're essentially right.There's at least one case for which an async reset can't be avoided - to ensure a definite state in the absence of a clock. There are designs in which some clock may not be running at all times. If there's at least one clock that is continuously running, then you can work around this by using this one clock to reset whatever state needs to be reset in another clock domain (making sure you handled domain-crossing properly), but there are cases for which there is just one clock that may not be running at all times, and you may thus need an async reset at some point to get the system in a definite state. I've had the case a few times.

author: NorthGuy
author_rank: Super Contributor
timestamp: August 08, 2020, 09:02:10 pm
content: Quote from: radar_macgyver on August 08, 2020, 08:08:25 pmI've never needed global reset, never used it. If I need to start over, I can always re-configure.I only use resets in different local modules, such as FSM may need a reset etc.

author: filssavi
author_rank: Frequent Contributor
timestamp: August 08, 2020, 09:32:49 pm
content: While this might make the code a little less portable, I tend to avoid resets where possible and rely on GSR mechanisms (Xilinx’s one namely) as the reset network can start to cause issues when pushing for 200+ MHz, as the fanout is extremely large and a large portion of the design will be affected by it

author: tggzzz
author_rank: Super Contributor
timestamp: August 08, 2020, 10:51:18 pm
content: Quote from: SiliconWizard on August 08, 2020, 08:33:56 pmAccepted, although I haven't personally come across that situation.There is one other reason for forcing a reset, even in a system like the OP's where there is a free-running counter and the hardware/system doesn't care its initial phase.ATE test vectors do require such a counter starts in a defined phase, so that it can pass/fail the counter at predetermined clock cycles.

author: mfro
author_rank: Regular Contributor
timestamp: August 10, 2020, 06:11:47 am
content: Quote from: SiliconWizard on August 08, 2020, 08:33:56 pmAltera/Intel FPGA FFs do have an asynchronous CLR that will be used as reset input. If you really need a reset, it is usually advisable to use that one (as synchronous resets eat up extra resources).They provide an application note with a safe sample implementation (search for AN545).And the problem is not the async reset itself, but the need to get out of it in a synchronous way...

author: Berni
author_rank: Super Contributor
timestamp: August 10, 2020, 07:21:29 am
content: This sync vs async reset thing comes up a lot because Xilinx(never use async) and Altera(use async) have conflicting recommendations for it.The reasoning behind Altera recommending async reset is because they have a dedicated async reset input on the logic blocks that goes directly to the flipflop. So adding a reset does not introduce any extra logic and so does not reduce performance. It does consume some wiring resources to wire them up tho, but can be routed using global clock routing line if needed to act like a GSR line.As for "But its async! What about hold time violations?!", well being async doesn't mean you just run that reset line directly out to a pin. There is often a synchronize that syncs the edge up to a clock, this makes things a lot more predictable. The compiler can make multiple instances of this synchronizer next to the logic to improve timings. You can also put multiple synhronizers in yourself to be able to match them into various clock domains. The point to it being async is that it is not part of the LABs synchronous timing path.Usually large blocks of logic coming out of reset on two different clock cycles is not an issue, but if they are required to come out of reset precisely together, then you baked this interdependancy into the very functionality of your logic. In that case you forced the compiler to meet timing closure across the multiple large blocks just by the way you designed it.

author: tggzzz
author_rank: Super Contributor
timestamp: August 10, 2020, 10:10:38 am
content: Quote from: mfro on August 10, 2020, 06:11:47 am... exactly as I stated!Quote from: Berni on August 10, 2020, 07:21:29 amPrecisely.It may work relatively easily in small designs where you aren't pushing the clock rate, but it doesn't scale very well.A problem with the FPGA place-and-route tools is that the detailed placement is a fractal function of the specific design (and apparently the phase of moon!); a trivial change can cause significant speed variation or timing margins. Yes, you can lock down the placement of parts of a design, but then routing becomes more problematic. NP complete problems are bitches

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 10, 2020, 04:28:45 pm
content: Quote from: tggzzz on August 08, 2020, 10:51:18 pmThat's quite possible, but the situation can actually happen more frequently than we think.Even without thinking of anything fancy, just take any design which controls the clock - you may run into this.Another range of examples is when the oscillator that provides the clock takes more time to start/stabilize than the FPGA takes to be fully configured, which can happen with PLLs for instance.A typical example I have run into a couple times: designs with several clock domains, with at least one clock domain for which the clock could stop (and start) at any moment, and for which you'd need to put some signals in this clock domain in a definite state when there is no clock running. There is no way you can do that in a synchronous way only. The approach I used was to monitor said clock with a process clocked from another clock domain (in which its own clock was guaranteed to run at all times), then generate a 'reset' signal if it detected the absence of clock in the other domain - reset signal that would be asynchronous for this other domain. This worked fairly well. I can give a concrete example: designs using an FTDI part (FT2232H/FT232H) in synchronous mode. In this mode, the FTDI chip provides the clock for the FIFO - but this clock only gets out of the IC when the IC is put in the synchronous mode, which is software controlled. So from the FPGA's POV, this clock can be in any state (running, not running) at any point in time. If you don't implement this reset mechanism, your FSM(s) controlling the FTDI chip can get stuck in any state and this won't be recoverable.As you said - even if this looks obvious - an asynchronous reset is asynchronous. In which case you'd need one? Obviously in cases where synchronous resets aren't appropriate.People used to writing HDL exclusively for FPGAs tend to be kind of biased towards them - which makes sense. So this is particularly true for this asynchronous reset thing due to how most FPGAs are structured. It can be appropriate when writing HDL for ASICs. This is why (unless as others have said, I run/expect to run into issues meeting timings) I usually write HDL that can be more or less used both on FPGAs and synthesized on silicon later on - unless I have a very specific reason not to.Something "hidden" in that whole discussion (although it has been mentioned regarding initialization) is that even if you don't explicitely implement async resets, most FPGAs have a GSR structure that ensures an initial state upon configuration. Strictly speaking, this can be seen as an asynchronous reset (that just happens to take a different path.)

author: tggzzz
author_rank: Super Contributor
timestamp: August 10, 2020, 04:47:15 pm
content: Agreed.You can't completely escape asynchronous signals, but every single one needs specific justification and careful examination.I remember asking my university tutor what happens if setup and hold times aren't met. I remember being disappointed in the waffly answer. The saving grace was that metastability was only just being recognised and quantified in the literature

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 10, 2020, 05:07:54 pm
content: Quote from: tggzzz on August 10, 2020, 04:47:15 pmYes. The same should be said about most of what we do, actually (but I admit we often tend to use "recipes" instead.)Quote from: tggzzz on August 10, 2020, 04:47:15 pmFrom what I've seen, this topic is still relatively poorly taught these days, unless you take advanced courses at PhD level - I don't think I'm exxagerating here. It gets worse. I've seen a number of young engineers getting our of their master's with an apparently decent command of HDLs - until your realize they don't know how to deal with clock domain crossing whatsoever.And related to the bias for FPGAs I talked about above: I think many university courses don't really teach the specifics of FPGAs, so students tend not to really grasp them. Which in turn makes them not really understand what is specific to FPGAs and what is more general for digital design.

author: tolpe
author_rank: Newbie
timestamp: August 12, 2020, 11:04:00 am
content: Quote from: SiliconWizard on August 10, 2020, 05:07:54 pmI could name a few prominent technical universities teaching "old school" VHDL knowledge which can be basically thrown away with new technologies (or when deviating from the local altera or xilinx monopolies that some schools have). It still tends to take years of practise in job to make a best score master student write robust designs.In my opinion academics should go back to good old 74xx breadboard practise before starting anything like VHDL or Verilog. Then the next thing is, learning the standard constructs inferring into the wanted logic. This kinda works ok in most cases, *if* some overhead was not in the way.Instead of working with logic, most students seem to get stuck with the complex semantics of language and complexity of vendor tools.With respect to the omnipresent reset issues, I found the MyHDL approach very elegant, which sticks the sync or async behaviour properties into the signal declaration. So you can switch your design easily for architecture specific inference, like for ASIC targets (where everything must be reset, explicitely - unless in a ROM cell). Learning to read Verilog or VHDL is still important, but for understanding logic, the language complexities and creating designs particular in VHDL are debatable.

author: tggzzz
author_rank: Super Contributor
timestamp: August 12, 2020, 02:01:11 pm
content: Quote from: SiliconWizard on August 10, 2020, 05:07:54 pmAppropriate proven "design patterns" are thoroughly good. They reduce design & documentation time, and have a higher probability of avoiding stupid errors.Stackexchange is full of recipes to be used - and promptly forgotten. No, I am not a fan of stackexchange.QuoteHow can there even be any PhD courses? At that level you are supposed to be selecting and doing somethingnovel.QuoteThey ought to realise where the dragons are, and some proven techniques. They won't necessarily have used them.QuoteThat wouldn't bother me too much, provided they have a solid grounding in the basics and can think how an FPGA or CPLD or etc maps onto the fundamentals. Metastability is one such fundamental.Overall, if a course is designed for one employer or job, then it is an apprenticeship or technician course - and that is just fine. Anengineeringcourse should teach the fundamentals that willlast a career and avoidteachingtoday's tech/tools. Those details can and will be learned on the job.

author: NorthGuy
author_rank: Super Contributor
timestamp: August 12, 2020, 02:05:46 pm
content: Quote from: tolpe on August 12, 2020, 11:04:00 amJust as electricians who know every detail of local electric codes, but may not know the Ohm's law. Such are times.

author: tggzzz
author_rank: Super Contributor
timestamp: August 12, 2020, 02:30:21 pm
content: Quote from: NorthGuy on August 12, 2020, 02:05:46 pmThat's not a bad analogy.OTOH I've always liked the story of the wandering Indian holy man that owned three posessions: lunghi, shoes, and megaphone. Those were essential to his lifestyle.

author: SiliconWizard
author_rank: Super Contributor
timestamp: August 12, 2020, 05:35:48 pm
content: Quote from: tggzzz on August 12, 2020, 02:01:11 pmBut you still have a lot to learn.I don't know about all PhD programs in all parts of the world, but taking advanced courses as part of your doctoral studies is not uncommon at all. Your original research is the dominant part of it of course, but you usually also have to take somes specific courses and also do some teaching in order to complete your PhD.Example:https://www.epfl.ch/education/phd/doctoral-studies-structure/Quote from: tggzzz on August 12, 2020, 02:01:11 pmI don't quite agree here. The very discussion in this thread (and in many other thread here) shows the problem. Those topics are still very poorly taught as far as I've seen. IME, most students don't grasp metastability issues well or know how to handle them.As to what is specific to FPGAs, the topic here would be an example, to understand why some vendors advise against async resets, whereas others don't, for instance. Also regarding signal initialization. Whereas they will work as expected on most FPGAs these days, they are certainly not synthesizable in general directly on silicon, so you typically get a range of different problems for initiliazing your signals properly.To me, this is kind of fundamental knowledge.

author: tggzzz
author_rank: Super Contributor
timestamp: August 12, 2020, 06:12:22 pm
content: I don't disagree, particularly about variability of PhDs and general knowledge.Nonetheless, metastability is pretty fundamental.

author: fourfathom
author_rank: Super Contributor
timestamp: August 12, 2020, 06:20:12 pm
content: Quote from: SiliconWizard on August 12, 2020, 05:35:48 pmI think much of this could be considered domain-specific knowledge, but yes, metastability is one area that should probably be taught in a general digital design engineering course.But I could be wrong -- I'm self-taught (no degree whatsoever) and began doing this stuff back in the days of RTL logic and using plastic tracing templates to draw my schematics. I cut my digital teeth on telecom systems having multiple asynchronous clocks and signals (from DC to 10 GHz) and ended the design portion of my career with Verilog and gate arrays. So I have no idea how this stuff is taught in school now.

author: Berni
author_rank: Super Contributor
timestamp: August 13, 2020, 05:49:51 am
content: I had a FPGA course as part of my electronics engineering degree. Haven't really gotten much useful knowledge out of it.It was mostly like. Here is what a FPGA is and what it does. Here is what the Xilinx tools look like (And told to download and install it by next class because its a huge download as usual). Here is how you set up a test bench and simulate it. Then the rest turned into a digital logic class of... this is how you build an adder, this is how you build a MUX, this is how you build RAM, this is how you build a state machine (with i think no mention of state encoding types). Then you also get to run a few designs on a dev board to see the process and that is it.Metastability? We never even heard about clock crossing or even timing analysis.

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 07:11:14 am
content: Quote from: Berni on August 13, 2020, 05:49:51 amThat sounds about right. There is a terrible amount of "push this button" associated with FPGA toolsets - and that becomes obsolete very rapidly.When I first thought about not observing ts/th(which lead to my understanding metastability), FPGAs were a decade in the future. All the fundamental work was done w.r.t. mainframe computer and long-distance plesiochronous telecom systems.Arguably, plesiochronous systems are a particularly nasty use case.

author: mfro
author_rank: Regular Contributor
timestamp: August 13, 2020, 07:21:55 am
content: IMHO, although it doesn't hurt, you do not need to understand metastability to get your timings right.It just needs the common sense that the data must be there before the clock. Just as you can't read a letter you didn't receive yet.Metastability is a lot more complex topic than just that.

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 07:59:16 am
content: Quote from: mfro on August 13, 2020, 07:21:55 amExactlyhow do youguaranteethat in a system with threeunrelatedclocks? (Or even two, but three makes the irreducable problem explicit)Consider the effects thatwillbe visible in plesiochronous systems where you have data arriving from several unrelated systems.There are computing equivalents that most people choose not to think about; they too cause "interesting" system failures.Background:Here is the famous <2 page letter:http://ibm-1401.info/AnomalousSynchronizer_ChaneyMolnar_IEEE1973.pdfHere are one of the author's recent thoughts, almost certainly "TL;DR"https://www.arl.wustl.edu/~jst/cse/260/glitchChaney.pdf

author: mfro
author_rank: Regular Contributor
timestamp: August 13, 2020, 08:38:51 am
content: Quote from: tggzzz on August 13, 2020, 07:59:16 amWith the only thing that helps: proper synchronisation.In the simplest case, a clocked shift register. In more difficult cases, with an asynchronous FIFO (admitted, writing an asynchronous FIFO *is* difficult, but I don't know anybody doing that other than for purely academic purpose anyway).You do not need to fully understand all the details of metastability to use these, it all boils down to the requirement for the data arriving before the capture clock.

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 08:56:42 am
content: Quote from: mfro on August 13, 2020, 08:38:51 amOf course, but those are mere workarounds since you can never ensure that, to use your phrase, "that the data must be there before the clock".As for async FIFOs, your experience is limited: they arefarmore than only of academic interest. They are sufficiently important that Mouser lists 102 differentdiscrete ICasync FIFOs, and DigiKey lists 816. You don't make and sell discrete ics that are only of academic interestNowadays they are usually buried inside an FPGA, where different clock domains meet.

author: mfro
author_rank: Regular Contributor
timestamp: August 13, 2020, 01:24:01 pm
content: Quote from: tggzzz on August 13, 2020, 08:56:42 amYou most likely don't buy async FIFOs at Mouser and cram them into your VHDL design, do you?I didn't say async FIFOs are not important (of course they are), I said nobody would write them from scratch but probably would use what the FPGA vendors supply.

author: tggzzz
author_rank: Super Contributor
timestamp: August 13, 2020, 01:48:44 pm
content: Quote from: mfro on August 13, 2020, 01:24:01 pmPlease don't create strawman arguments by deliberately snipping relevant paragraphs. That just annoys people and makes you look foolish. In this case, which bit of this don't you understand?Quote from: tggzzz on August 13, 2020, 08:56:42 amThen you claimed:QuoteIs that what you had that in mind when you did write:Quote from: mfro on August 13, 2020, 08:38:51 am

author: NorthGuy
author_rank: Super Contributor
timestamp: August 13, 2020, 01:52:34 pm
content: Quote from: mfro on August 13, 2020, 07:21:55 amAnd after. You need toholdyour letter until it is read.Of course, you can figure out how to do timing analysis using common sense. You just need to think for few hours (or few days).The problem is that people try to do away with structural things (such as gates and flops), and try to concentrate on behavioural things - find good language constructs (VHDL has so many ...) and such. Then it's getting very difficult to link their design to the timing requirements of flip flops. Newton's laws are also common sense, yet they haven't been discovered for thousands of years - people didn't think in the right direction.

author: mfro
author_rank: Regular Contributor
timestamp: August 13, 2020, 03:17:56 pm
content: Quote from: tggzzz on August 13, 2020, 01:48:44 pmApologize if my statement wasn't clear enough. I thought it was obvious when I stated nobodywritesasync fifos that I didn't mean nobodyusesasync fifos (let alone when I said before youneedthem for more complex synchronisers)?

author: Bassman59
author_rank: Super Contributor
timestamp: August 13, 2020, 06:41:49 pm
content: Quote from: NorthGuy on August 13, 2020, 01:52:34 pmExactly.Consider: you have a data bus with a data valid flag, generated on one clock. The data bus is driven with a new value at the same time the flag is asserted.In the other clock domain, you synchronize the flag, perhaps using two flip-flops in series clocked by that destination clock. Logic in that destination domain recognizes the assertion of the synchronized flag and latches the data bus. At the same time, a "clear flag" signal goes back to the source domain to do exactly that -- clear the data-valid flag.I am not convinced that the data bus needs to be synchronized to the destination domain's clock. Only the flag needs such.The timing analysis must be considered, with a path constraint. The assumption made above is that the data bus settles at the destination latches before the flag is recognized.You may not even need the handshake. If the destination domain is faster than the source domain, you just synchronize the flag, detect its assertion and when that's true you latch your data bus. If the destination domain is slower than the source domain, the source needs to keep the flag true long enough to be recognized in the destination domain. So if your source clock is 100 MHz and your destination clock is 25 MHz, assert the flag (in the source domain) for 8 clocks.There are many ways to handle this.

author: Berni
author_rank: Super Contributor
timestamp: August 13, 2020, 07:13:18 pm
content: Yep that's the whole point behind holding the data.It has to stay on the bus long enough for the other end to look at it and use it. This also brings into why designs are made synchronous if possible. If the other side knows exactly when to look at the data then the data only needs to be there for 1 clock cycle (Or even just half a clock cycle in DDR) before the bus can already put new data on it.But usually when i do need to do clock crossing i just stick a small FIFO in there so its not my problem anymore.

author: mfro
author_rank: Regular Contributor
timestamp: August 14, 2020, 06:00:01 am
content: Quote from: Bassman59 on August 13, 2020, 06:41:49 pmIn that example (with both clocks being exact multiples), you often don't need synchronisers at all (provided both clocks stay synchronous, i.e. are driven by the same PLL).You just need to make sure you hold your signals long enough in the fast clock domain so that your slow domain can see them.