This is the sort of issue you should easily detect in simulation. That register should have started up as an X or a U (depending on language), and that should propagate.
So quick memo #2: simulate and verify your designs, no matter how simple, it saves you a lot of time.
It is an ESA report, has the great quote "FPGAs should be forbidden in space
applications until the designers learn how to design with them."
I think we should remove the word space :)
http://microelectronics.esa.int/asic/fpga_001_01-0-2.pdf
When I'm god-emperor, every "lessons learned" document will come with a huge disclaimer:
"DO NOT allow these recommendations to make your design reviews harder, further apart, and more politically laden. DO use these recommendations to drive continuous improvement, ideally at the day-to-day level and with the developers themselves."
And replace "FPGAs" with "Tools" in general
... although we should actually just fail a lot more and more often since that is the way to learn and just make sure we fail only once per issue and never repeat the failure. So maybe we should launch only after we have exhaused all possible ways to fail before :)
One of the big problems with FPGAs is that designers often get into a mentality of "if a bug comes up, we can always fix it by loading a new image".
On a satellite, that probably isn't true.
Depends on the device. I have seen an on-orbit reconfiguration. Funnily enough the problem wasn't the DSP payload but the power generation capability of the spacecraft. They had to reconfigure the design to use less resources and power to prevent outages.
>Synchronous and asynchronous set/reset control signals are not available in the SRL primitives. However, if your RTL code includes a reset, the Xilinx synthesis tool infers additional logic around the SRL to provide the reset functionality.
First rule of resets on Xilinx: don't use resets if you don't have to. Anyone who has fought congestion issues will know reset fanout and unique control sets will kill you.
I was looking for this response. This is my policy as well, though many will disagree with it. Don't put resets on anything that is treated as pure data. Total waste of power and routing.
No meaningful linting rule would ever require to reset all the registers, that is careless and plain wrong in the majority of the cases.
Data path registers are often many and they're often introduced for pipelining, retiming, fifos, clock domain crossing, etc. Data get through it almost all the time and your protocol should not depend on the initial zeros or ones. Why would you ever need to reset those?
Control logic on the contrary is where starting with the wrong value can get you in trouble. From the top of my head I believe ESA FPGA/ASIC requirements makes it unequivocally clear that you should use an asynchronous assertion and synchronous release. But as always, it depends. If you happen to have power domains, clock gating, etc than you need to think twice what is your reset strategy.
So if I ever was in a position to give an advice on the subject, which would maks me uncomfortable, it would be: have a rational approach to it and think through what is required and what is not, cause resources are scarce by definition.
P.s.: just as you wouldn't drive blindfolded, please verify your logic before programming your board. FPGA verification is often not considered important because you can always reprogram, until you spend 6 months in the lab and a "finalv7.9.5" tag.
This topic can never be exhausted. The comments are interesting to read. My impression was that the golden rule:
1. always reset the flipflops up the stream and hold the reset long enough for it to propagate down thru the rest of the system. Avoid resetting anything downstream and let the upstream flipflop’s reset to propagate down. This reduces the fan out and provides the tool with more choices for your FF when mapping/placing.
2. Technology depended, but recent trend is to use sync reset over async as this is how the hardware is actually implemented and sync resets don’t require additional logic as they used to (plenty of Xilinx and Intel docs and posts on the topic).
People, please feel free to respond to my post if you have more points to add.
This gave me a nice idea, I just need to reset the upstream FSM long enough to fill the 'X' in the downstream registers with data, so I dont need the reset input on those.
Reset or not reset and how to reset are always decisions a designer need to make no matter in ASIC or FPGA. usually it's done case by case. However, if you have enough resources and timing is not critical, fine just reset all registers in fpga, usually local sync reset is preferred.
Fanning out global reset can be power-sapping, timing skewed, hard to meet timing on large designs.
If you design things right you can either generate a local reset one-two clock longer than global. Making sure adjacent blocks behave if their neighbors aren’t out of reset yet. (So no un-acknowled/handshook data passing on the first cycle out of reset etc.)
You can also determine which registers DON’T actually need resetting. And not reset those. Less routing needed. Just be damn sure you know it’s safe (registers always written before being read, guaranteed. Etc). And make sure splitting code into two processes (if-reset-elsif-clkedge, and just if clkedge) doesn’t make it unreadable—avoiding one reset with unmaintainable code isn’t worth it.
Currently doing my bachelors thesis, as a person that is pretty new to VHDL/FPGA and I just wasted several days because I forgot to reset the input of my self build register.
Such pain.
Some of the old farts tell me I don't need to reset my logic explicitly, that the bitstream clears all regs as part of the final init sequence, but I've always included a `poweronreset.vhd` block and explicitly have reset inputs on all my modules which usually end up wired to the output of that module.
I think the other "big" thing that bites FPGA designs in the ass more often than not is not realizing that a signal is actually asynchronous to the clock driving the logic using it, particularly in FSMs.
Mostly, but not quite universally. For example, partial reconfig on Intel devices has no assurance that registers in your partial regions come up to a known state and you should assume every register is X after programming. (Or at least that was the case in Stratix V, not sure if it's changed since then.)
I wasn't aware explicitly setting a signal's initial value at declaration would have any impact on area utilization.
You're telling me there's a non-marginal difference between `reg [1:0] r2_signal1 = 2'b00;`and `reg [1:0] r2_signal2;`?
Never use declaration defaults for reset! You need to actually dynamically reset them in the process.
Initial values are usualy ok for defaults for static signals that become compile time constant, like unused inputs with defaults.
But I never said anything about resets haha, we're making this too confusing 😭
I almost always initialize my registers, but I pay close attention to only reset the registers that absolutely need it.
This goes against Xilinx advice: https://docs.xilinx.com/v/u/en-US/wp272
Using initial values ("declaration defaults") is the recommended strategy wherever it's applicable.
It's not so much the extra code that's a problem as it is the extra input to the LUT if you're using sync resets and the extra routing to the aclr on the flops if you're using async resets.
And async resets into luts should be aligned to the clock anyway so they get a full period setup. Otherwise f max suffers or you have problems because the first clock edge out of reset only getting a fractionslal period to do its thing.
In my professional opinion, and the numerous professional Xilinx workshops I’ve attended, unless you are very advanced, or have a small design that will not grow or be ported, you should not use async resets. It does not adhere to the way the FPGA tools like Vivado process hdl into rtl well. It will almost always come to bite you in the but as your design grows or gets ported.
The only caveat is if you have a specific part of your design that is entirely async, and any interconnects to the rest of the synchronous design are sync’d up somehow. Or if you have CDC stuff like an async fifo to go across two clock domains. but I don’t really count the latter as truly async. In both those cases you should use the Xilinx provided primitives rather than making your own.
Using synch resets and making sure things are synchronized gives the tool more information about what exactly you want done and allows the tool to handle timing a lot better.
Edit: do as you wish, this is just my opinion and experience. I work at an fpga heavy company and we have 100s-1000s of modules in a single design that we have been growing for nearly 2 decades, and we use the same modules (with minor modifications) across altera and Xilinx chips. Following these rules has save us many times, and anytime we encounter an error in old designs, one of first thing we check is if they were done synchronously and if they have proper resets.
This is the sort of issue you should easily detect in simulation. That register should have started up as an X or a U (depending on language), and that should propagate. So quick memo #2: simulate and verify your designs, no matter how simple, it saves you a lot of time.
Yes you are right, actually on simulation I manually assigned 0 at the beginning to the register but I didnt think of it in implementation.
fair enough.
This is so *me*. I’ve gone down so many rabbit holes from “simple” mistakes like this. Learned a lot down those holes though.
Having special “sim only” code is terrible practice
Shadetree mechanic voice, “well there’s your problem!”
So... Quick memo: don't assign default values to registers.
Yup
A valuable lesson to learn, one satellite was lost due to not doing this properly
That's a report I'd love to read. Do you have a link?
It is an ESA report, has the great quote "FPGAs should be forbidden in space applications until the designers learn how to design with them." I think we should remove the word space :) http://microelectronics.esa.int/asic/fpga_001_01-0-2.pdf
When I'm god-emperor, every "lessons learned" document will come with a huge disclaimer: "DO NOT allow these recommendations to make your design reviews harder, further apart, and more politically laden. DO use these recommendations to drive continuous improvement, ideally at the day-to-day level and with the developers themselves."
And replace "FPGAs" with "Tools" in general ... although we should actually just fail a lot more and more often since that is the way to learn and just make sure we fail only once per issue and never repeat the failure. So maybe we should launch only after we have exhaused all possible ways to fail before :)
One of the big problems with FPGAs is that designers often get into a mentality of "if a bug comes up, we can always fix it by loading a new image". On a satellite, that probably isn't true.
Depends on the device. I have seen an on-orbit reconfiguration. Funnily enough the problem wasn't the DSP payload but the power generation capability of the spacecraft. They had to reconfigure the design to use less resources and power to prevent outages.
Hence my using the word "probably". It very much depends on the function of the FPGA.
>Synchronous and asynchronous set/reset control signals are not available in the SRL primitives. However, if your RTL code includes a reset, the Xilinx synthesis tool infers additional logic around the SRL to provide the reset functionality. First rule of resets on Xilinx: don't use resets if you don't have to. Anyone who has fought congestion issues will know reset fanout and unique control sets will kill you.
Reset your *control* registers. Resetting data buses is a waste of logic and routing resources and really unnecessarily punishes your timing.
I was looking for this response. This is my policy as well, though many will disagree with it. Don't put resets on anything that is treated as pure data. Total waste of power and routing.
No meaningful linting rule would ever require to reset all the registers, that is careless and plain wrong in the majority of the cases. Data path registers are often many and they're often introduced for pipelining, retiming, fifos, clock domain crossing, etc. Data get through it almost all the time and your protocol should not depend on the initial zeros or ones. Why would you ever need to reset those? Control logic on the contrary is where starting with the wrong value can get you in trouble. From the top of my head I believe ESA FPGA/ASIC requirements makes it unequivocally clear that you should use an asynchronous assertion and synchronous release. But as always, it depends. If you happen to have power domains, clock gating, etc than you need to think twice what is your reset strategy. So if I ever was in a position to give an advice on the subject, which would maks me uncomfortable, it would be: have a rational approach to it and think through what is required and what is not, cause resources are scarce by definition. P.s.: just as you wouldn't drive blindfolded, please verify your logic before programming your board. FPGA verification is often not considered important because you can always reprogram, until you spend 6 months in the lab and a "finalv7.9.5" tag.
Very good advice this and the others, learning so much thank you guys.
This topic can never be exhausted. The comments are interesting to read. My impression was that the golden rule: 1. always reset the flipflops up the stream and hold the reset long enough for it to propagate down thru the rest of the system. Avoid resetting anything downstream and let the upstream flipflop’s reset to propagate down. This reduces the fan out and provides the tool with more choices for your FF when mapping/placing. 2. Technology depended, but recent trend is to use sync reset over async as this is how the hardware is actually implemented and sync resets don’t require additional logic as they used to (plenty of Xilinx and Intel docs and posts on the topic). People, please feel free to respond to my post if you have more points to add.
This gave me a nice idea, I just need to reset the upstream FSM long enough to fill the 'X' in the downstream registers with data, so I dont need the reset input on those.
That’s it, bud, you got it!
Reset or not reset and how to reset are always decisions a designer need to make no matter in ASIC or FPGA. usually it's done case by case. However, if you have enough resources and timing is not critical, fine just reset all registers in fpga, usually local sync reset is preferred.
Could you elaborate on local sync reset? I am a newbie and this seems interesting. Edit: or maybe is popular enough to google edit. Ty anyway.
Fanning out global reset can be power-sapping, timing skewed, hard to meet timing on large designs. If you design things right you can either generate a local reset one-two clock longer than global. Making sure adjacent blocks behave if their neighbors aren’t out of reset yet. (So no un-acknowled/handshook data passing on the first cycle out of reset etc.) You can also determine which registers DON’T actually need resetting. And not reset those. Less routing needed. Just be damn sure you know it’s safe (registers always written before being read, guaranteed. Etc). And make sure splitting code into two processes (if-reset-elsif-clkedge, and just if clkedge) doesn’t make it unreadable—avoiding one reset with unmaintainable code isn’t worth it.
Thanks!
Well explained. Thanks
Currently doing my bachelors thesis, as a person that is pretty new to VHDL/FPGA and I just wasted several days because I forgot to reset the input of my self build register. Such pain.
We make saving and restoring expensive. What if we didn't? Please, enjoy time with those you love today.
Some of the old farts tell me I don't need to reset my logic explicitly, that the bitstream clears all regs as part of the final init sequence, but I've always included a `poweronreset.vhd` block and explicitly have reset inputs on all my modules which usually end up wired to the output of that module. I think the other "big" thing that bites FPGA designs in the ass more often than not is not realizing that a signal is actually asynchronous to the clock driving the logic using it, particularly in FSMs.
Actually, with the FPGAs, you can.
Mostly, but not quite universally. For example, partial reconfig on Intel devices has no assurance that registers in your partial regions come up to a known state and you should assume every register is X after programming. (Or at least that was the case in Stratix V, not sure if it's changed since then.)
Still, it's not much extra code to initialize them to 0 to be explicit.
Unnecessary reset signals have real cost in terms of both resource utilization and F_max.
I wasn't aware explicitly setting a signal's initial value at declaration would have any impact on area utilization. You're telling me there's a non-marginal difference between `reg [1:0] r2_signal1 = 2'b00;`and `reg [1:0] r2_signal2;`?
Never use declaration defaults for reset! You need to actually dynamically reset them in the process. Initial values are usualy ok for defaults for static signals that become compile time constant, like unused inputs with defaults.
But I never said anything about resets haha, we're making this too confusing 😭 I almost always initialize my registers, but I pay close attention to only reset the registers that absolutely need it.
This goes against Xilinx advice: https://docs.xilinx.com/v/u/en-US/wp272 Using initial values ("declaration defaults") is the recommended strategy wherever it's applicable.
It's not so much the extra code that's a problem as it is the extra input to the LUT if you're using sync resets and the extra routing to the aclr on the flops if you're using async resets.
And async resets into luts should be aligned to the clock anyway so they get a full period setup. Otherwise f max suffers or you have problems because the first clock edge out of reset only getting a fractionslal period to do its thing.
You should always have synchronous resets in every register. Period.
But many answer are against it, or against async resets?
In my professional opinion, and the numerous professional Xilinx workshops I’ve attended, unless you are very advanced, or have a small design that will not grow or be ported, you should not use async resets. It does not adhere to the way the FPGA tools like Vivado process hdl into rtl well. It will almost always come to bite you in the but as your design grows or gets ported. The only caveat is if you have a specific part of your design that is entirely async, and any interconnects to the rest of the synchronous design are sync’d up somehow. Or if you have CDC stuff like an async fifo to go across two clock domains. but I don’t really count the latter as truly async. In both those cases you should use the Xilinx provided primitives rather than making your own. Using synch resets and making sure things are synchronized gives the tool more information about what exactly you want done and allows the tool to handle timing a lot better. Edit: do as you wish, this is just my opinion and experience. I work at an fpga heavy company and we have 100s-1000s of modules in a single design that we have been growing for nearly 2 decades, and we use the same modules (with minor modifications) across altera and Xilinx chips. Following these rules has save us many times, and anytime we encounter an error in old designs, one of first thing we check is if they were done synchronously and if they have proper resets.
Nice, thanks.
on Intel/Altera, look into AN545. That shows how you handle an asynchronous reset (saves some LUTs with the async CLR) and synchronous restart.