Blog

Thoughts on IC development, EDA, and hardware design languages.

EDA Tool Developer Series: What The Flop? … Part 3

Posted by: Trent McClements | Posted on: April 21st, 2015 | 1 Comments

Share on LinkedIn31Share on Facebook0Tweet about this on Twitter0Share on Google+0Email this to someone

In our previous two posts we gave a basic overview of flop detection and the anomalies that can occur in sensitivity lists. In this post we’ll further discuss the subtlety of flop inference within an EDA tool, specifically looking at clocks and resets and how flop inference isn’t solely based on sensitivity list analysis.

Before we get into that I should make a small point as I got some feedback about posting incorrect and poorly structured SystemVerilog syntax in this blog last go around. To be clear, I am not trying to promote poor coding conventions. After years designing RTL blocks and taping out ASICs, doing FPGA prototyping and emulation, along with verification and post-silicon validation/debug I have read and written a lot of VHDL, Verilog and SystemVerilog. I’ve seen great code along with very poor code and undecipherable code! Given a choice, of course, I’d only see the former from now on. Unfortunately, when developing EDA tools you don’t get to choose your input quality and must create your tool such that it is robust to the worst-of-the-worst HDL input (at the very least so you can create an error). That’s what we’re trying to accomplish here, showing what you could see as input HDL, not teaching how HDL code should be written or structured. Hopefully this will help make future EDA tools that much better and more stable!

With our EDA Tool Developer hat on, let’s look at a basic flop and it’s associated clock.

always @(posedge clk)
q <= d;

A quick look at the above code shows that the flops clock is clk as clk is the edge-sensitive signal and is not referenced within the process body. Now, consider a flop with a synchronous reset signal, rstb.

always @(posedge clk)
if (~rstb) q <= 1'b0;
else q <= d;

Again, not much here. The flop q is edge sensitive to clk only and as such the reference to rstb must be synchronous. Now, let’s take another step and make this flop asynchronously reset.

always @(posedge clk or negedge rstb)
if (~rstb) q <= 1'b0;
else q <= d;

Note that the sensitivity list now contains an edge-sensitive reference to the rstb signal and rstb is referenced within the process body whereas clk is not. As such, clk is the clocking signal and rstb is an active low, asynchronous input to the flop q. Everything so far is basic HDL 101 that we all learned in school. But things can get tricky. For instance, what happens if q is assigned to a non-constant value in the positive clause of the if-else?

Problem Case 1
always @(posedge clk or negedge rstb)
if (~rstb)q <= ~d;
else q <= d;

What’s been inferred here is actually a strange double-clocked flop where rstb is both a clock and conditions the value assigned to q on the positive edge of clk. Since the flop structure is clocked by two separate signals this is generally not considered a flip-flop structure by EDA tools.

Now let’s say you have an async set-reset flop.

always @(posedge clk or negedge rstb or negedge setb)
if (~rstb) q <= 1'b0;
else if (~setb) q <= 1'b1;
else q <= d;

Again, this is fine (assuming your synthesis library supports this type of structure) since you only have one clocking signal, clk and two asynchronous inputs (though rstb has priority over setb). The trouble occurs when you see code such as this.

Problem Case 2
always @(posedge clk or negedge rstb or negedge setb)
if (~rstb) q <= 1'b0;
else q <= d;

Now you’ve suddenly got a double-clocked signal in q, as both setb and clk do not appear in the process body. It’s very likely this is a simple typo or bug and not design intent but regardless, you could see this structure and have to deal with it nicely.

Another issue comes in the form of more traditional DDR flops. These structures do exist, though I’ve never seen them in a standard cell library (or at least never been allowed to use them when they did exist).

always @(posedge clk or negedge clk)
q <= d;

Again, perfectly legal as per the SystemVerilog LRM but may not be appropriate for your tool. For completeness I should note that the above code is distinctly different than the following (though we did discuss the edge-sensitivity requirement for flop detection in a previous post).

Problem Case 3
always @(clk)
q <= d;

At least from a synthesis versus simulation point of view. The example in “Problem Case 3″ is not just sensitive to edges on clk but also to any transition (X to Z, Z to 1, etc).

So, the main take-away from all of the above is that once you get past the basics of clock and reset inference you are stuck doing a more complex data-flow analysis of the process body to really understand what structures are being inferred. You cannot simply look at sensitivity lists to infer flops but rather have to push down into the process body and start to understand what impact the sensitivity list signals have over the process output signals.

Have you run into any strange flop coding styles that slipped through a synthesis tool? Perhaps got caught using DDR flop cells when you didn’t mean to? We’d love to hear about it in the comments!

4-Ways-to-Build-Best-in-Class

Share on LinkedIn31Share on Facebook0Tweet about this on Twitter0Share on Google+0Email this to someone

Comments (1)


  1. somashekar Y - Reply
    April 25, 2015

    Good content useful for beginners!

Leave a Comment