Synchronous Resets
I've been using the "last assignment wins" for resets for >5 years. Personally I find it easier to read and it saves having to needlessly indent the entire process one level. I've never seen any problems using this coding style with the FPGA synthesis tools I use (ISE, Quartus, Synplify).
Asynchronous Resets
To answer your bonus question regarding asynchronous resets - this is a little trickier. Consider the following:
typedef struct packed {
logic a;
logic b;
} state_t;
state_t state;
always_ff @(posedge clk or negedge areset_n) begin
if (~areset_n) begin
state.a <= 1'b0;
end else begin
state.a <= data_a;
state.b <= data_b;
end
end
We have a bit of a problem. We don't want state.b
to have a reset, but it's part of the same structure as state.a
which is reset. Being good engineers we use always_ff
processes but this actually means we can't split the code into separate processes. Besides, it would become very messy and error prone keeping track of which members are assigned in which process for a large state structure.
The above code actually synthesises to the following:
We can see that the areset_n
signal acts as an enable to the state.b
register. Typically this isn't what we want, and since most FPGAs don't support this architecture natively the synthesis tool is forced to insert additional logic to emulate the enable:
This extra logic reduces timing margin and uses up precious resource. Thankfully, there is a workaround:
always_ff @(posedge clk or negedge areset_n) begin
if (~areset_n) begin
state.a <= 1'b0;
state.b <= 1'bx;
end else begin
state.a <= data_a;
state.b <= data_b;
end
end
Note that we have assigned x
to state.b
during the reset. As we can see, Quartus now synthesises our intended circuit:
Bonus Rant
As an aside, I'm not a big fan of being constrained to "standard practice" because the possibility that tools might get is wrong. "Conventional wisdom" is often incorrect or outdated.
Be adventurous and push the tools to their limits. If you hit a bug in the tool or a limitation then raise a bug with the vendor and adjust your style to compensate. Sure sometimes you'll spend time looking into a strange bug that turns out to be the fault of the toolchain but you should be looking at the output of your tools anyway. The time spent will be more than saved by the improved levels of abstraction and re-use made available with some of the newer language features.
If more of us pushed to get new features supported or participated in improving the languages then vendors wouldn't be able to get away with fobbing us all off with tools that are already 5-years out of date! The level of conservatism in RTL development hampers innovation - we love complaining about the tools but we don't participate enough in making them better.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…