Reason for LUT1_L buffer insertion in Synplify EDIFs?

When generating EDIF from Synplify, I frequently notice buffers (LUT1_L primitives with INIT property of 2) inserted in the circuit. Does anybody know why the tool is doing this and/or whether it can be disabled?

I realize that the presence of buffers with local outputs can suggest some packing hints, but I've also seen the likes of a LUT1_L buffer driving nothing but an inverter, in which case the buffer seems superfluous and the packing assumption falls apart.

I'm a little uncertain on how to proceed with the buffers (32 of them out of 155 total cells in a 32-bit counter circuit), because I am using the generated EDIF as an input to custom CAD tools. In general I just trim these buffers -- I don't want to allocate LUTs that serve only as glorified pass-throughs -- but I'm still wondering why they're there in the first place, and whether they are actually supposed to serve some useful purpose. If I didn't know that Synplify generates high quality output, I would be much less puzzled.

This is with Synplify Pro 8.4, in projects targeting an XC2VP30-6-FF896.

Reply to
Neil Steiner
Loading thread data ...

While the INIT property of 2 leaves me a little confused (I would expect

1 or 0 for a LUT1) the presence of "glorified pass-through" elements are often required to drive carry chains properly. Do you know the structure of the slice very well? I have a graphic of the slice internals pinned to my cubicle wall to refer to anytime I see something odd in my Synplify HDL Analyst technology view, usually because my coding comes up with something that doesn't fit the way I expect with the tool most often doing the right thing for the RTL I've presented. I usually just need to tweak my thinking and the code to get the "clean" results I thought I'd get the first round.

- John_H

Reply to
John_H

Thanks for the response, John.

Let's see if I can get this right. A 1-input LUT is a 2-bit RAM. In the case of a buffer, the 10 (binary) value gets replicated as

1010101010101010 and inverted to 0101010101010101. The MSB of that word is addressed when all inputs are zero, so {A1,A2,A3,A4}={0,0,0,0} returns 0. More generally, {A1,A2,A3,A4}={0,x,x,x} returns 0, and {A1,A2,A3,A4}={1,x,x,x} returns 1. It's this weird LUT math thing ... ;)

... and I will concede that there are carry chain elements on nearby nets ...

I do. That's not to say I can't be making a mistake, but I'm quite familiar with the FPGA Editor view, as well as the rules about what can and cannot be mixed and matched within a slice. (Not all of the actual rules are apparent from the FPGA Editor view.) From a slice component perspective, I have yet to find a situation where these buffers were strictly required. Or stated differently, even though I trim the buffers, the implementations still work properly in hardware.

That does make sense, but I'm seeing behavior like this even in the trivially simple case of a 32-bit counter:

process(clk) begin if rising_edge(clk) then if reset = '1' then reg '0'); else reg

Reply to
Neil Steiner

Synplify has changed how they do this several times over the years. I'm pretty sure they insert the buffers if the logic preceding the carry chain would cause the carry chain to be broken by the optimization without the lut buffers. They had a problem with earlier releases where a constant on one of the bit inputs to the carry chain would cause the carry chain to be broken into two segments, which made for some pretty ugly mappings. The LUT1 mapping though does occasionally cause problems, notably when there is an instantiated or keep-buffered lut (done to strongly hint to the synthesis that you want it done in a particular way) followed by an inferred carry chain.

Reply to
Ray Andraka

In Verilog, I'd rearrange the equation to always add one to a value that's dependent on the synchronous reset such as

always @(posedge clk) reg

Reply to
John_H

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.