XST synthesis gripe/sub-optimization

J

johnp

Guest
I've been bitten several times by XST producing sub-optimal results by
trying to use the flip-flop enable when it doesn't need to. We all
know
the priority of Reset/Set/Enable to ensure that the flip-flop pins can
be
used, but if you need to violate this, then may create stupid logic.

For example:

always @(posedge Clk10 or posedge reset)
if (reset)
timeout_intr_reg <= #1 1'b0;
else if (lc_intr_reg_wr)
timeout_intr_reg <= #1 db_wr_data_r2[6];
else if (intr_db_timeout)
timeout_intr_reg <= #1 1'b1;

Produced logic that tried to use the Enable pin, thus it added logic
to drive the enable using since there was no one signal that could
directly drive the enable. The code can't be re-ordered because
of the required priority.

Note that, excluding reset, there are 4 signals involved in the logic.
Thus
all the logic could fit into one LUT driving the D pin to the flip
flop,
no need to use the enable at all.

Identical functionality:
if (reset)
timeout_intr_reg <= #1 1'b0;
else
timeout_intr_reg <= #1 lc_intr_reg_wr ? db_wr_data_r2[6] :
(timeout_intr_reg | intr_db_timeout);

This second version synthesized nicely and gave me the margin I needed
to meet
timing. It's not as clear as the original, however.

Can XST be made to recognize cases like this? Just because you have an
enable pin on the flip-flops doesn't mean you have to use it!

Anyone else seeing this?

John Providenza
 
On 8 Mar 2006 08:47:36 -0800, "johnp" <johnp3+nospam@probo.com> wrote:

I've been bitten several times by XST producing sub-optimal results by
trying to use the flip-flop enable when it doesn't need to. We all
know
the priority of Reset/Set/Enable to ensure that the flip-flop pins can
be
used, but if you need to violate this, then may create stupid logic.

For example:

always @(posedge Clk10 or posedge reset)
if (reset)
timeout_intr_reg <= #1 1'b0;
else if (lc_intr_reg_wr)
timeout_intr_reg <= #1 db_wr_data_r2[6];
else if (intr_db_timeout)
timeout_intr_reg <= #1 1'b1;

Produced logic that tried to use the Enable pin, thus it added logic
to drive the enable using since there was no one signal that could
directly drive the enable. The code can't be re-ordered because
of the required priority.

Note that, excluding reset, there are 4 signals involved in the logic.
Thus
all the logic could fit into one LUT driving the D pin to the flip
flop,
no need to use the enable at all.

Identical functionality:
if (reset)
timeout_intr_reg <= #1 1'b0;
else
timeout_intr_reg <= #1 lc_intr_reg_wr ? db_wr_data_r2[6] :
(timeout_intr_reg | intr_db_timeout);

This second version synthesized nicely and gave me the margin I needed
to meet
timing. It's not as clear as the original, however.

Can XST be made to recognize cases like this? Just because you have an
enable pin on the flip-flops doesn't mean you have to use it!

Anyone else seeing this?
Yes.

My experience is that if you don't have a trailing 'else' you will get
a clock enable. XST sees that the the output ff (i.e.
timeout_intr_reg) is only assigned to under certain conditions, and
says "Aha! I can use a clock enable!" even if that doesn't result in
optimal logic.

In the cases I can remember, it was sufficient to add the 'else' so
that the output ff always gets assigned a value, even if that is
something trivial like

....
else if (intr_db_timeout)
timeout_intr_reg <= #1 1'b1;
+ else
+ timeout_intr_reg <= timeout_intr_reg;

It's a good idea to add a small comment to your code to explain why
this was done, e.g. // avoid clock enable inference in XST.


Disclaimer: I haven't used XST past version 6.3.3.
(8.something is out now.)


Regards,
Allan
 

Welcome to EDABoard.com

Sponsor

Back
Top