That depends. I tend to keep most of my critical logic synchronous, i.e. master state machines, chip enable circuits, etc. But too many modules with reset edge sensitivity can result in timing problems. Lots of synchronous resets throughout a design, in my experience, can cause quite a bit of headache with already tightly-timed designs.
I find it best to analyze what portions of a circuit don't really need synchronous resets, and keep them asynchronous.
Before too many people say "yeah, sure, everything's always zero" keep in mind that without the asynchronous reset in your design the synthesizer may feel free to implement more compact logic using the synchronous set and reset in your registers. This will still leave you with 0 startup values for all *reset* registers but those registers that are implemented with synchronous *set* functions will initialize to a LOGIC 1.
I have spent time in my code getting the synthesis initial values to match up with the reset-free design's implementation, using xilinx INIT=R attributes for FDS or FDSE primitives that should be reset at startup and INIT=S values for the FD, FDR, FDRS, FDE, FDRE, AND FDRSE registers that neede to initialize to a logic 1.
As a Verilog designer I can now take advantage of initial assignments when I declare a register in *some* synthesizers where the
reg [7:0] counter = 8'h2f;
declaration will set the initial-state for the individual counter bits different than the '00 that should end up there without the initial assignment. XST does this, Synplify does not. XST may not be perfect at this (a register that should have been one SRL broke into several SRLs, one for each binary-one initial value) but may have tweaked the implementation since last I looked into the issue.
So, beware the synchronous set when you don't use the INIT attribute.
The best is to have an asynchronous reset that is released synchronous. This works even if the clock is not running. Eg with a broken crystal. There are app notes how to do this. Basicly it is a shift register stage resetted asynchronously with an inactive signal at the data input. After release of reset the inactive reset will clock towards the output. With this you can even build up a tree for large FPGAs to prevent slowing down clock rate because of large routes.
Actually, with Xilinx FPGA's you are better off using a strictly synchronous reset, and only on the flip-flops that need it.
If you need the behavior of an async reset, meaning the pins all go to a safe state, pull the program pin low. That immediately puts the FPGA into the programming state, which will look like it has been reset.
Sometimes you need defined outputs even if there is no clock. In such cases, pulling the prog line low may not cut it. In such cases, an asynchronously asserted, and syncrhonously deasserted, asynchronous reset is the safest option.
But, like Ray said, you often don't need reset everywhere.
As to the initial values after configuration, remember that the end of configuration is likely to be asynchronous to your clock, so for example, a down counter initialized to a zero may not be a good idea! In general, down counters should be initialized to odd values, and up counters should be initialised to even values, to avoid having an uncertainty in more than one bit (the LSB) on the first clock at/after reset/config.
For synchronous deassertion of asynchronous resets, another option is to disable the clock until several periods after reset is deasserted, giving it time to propagate to all targets.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.