What's the difference for VHDL code between simulation and synthesis?

KJ wrote: (snip)

Absolute delays will likely never be synthesizable, for example.

(snip)

On the other hand, if it can be done why not do it as a module. (That would be verilog, but VHDL has something similar.)

Most don't synthesize a variable divide, but usually one would want to use a module, anyway. (For example, to do a pipelined divide.)

Unless the hardware implemented a two edge FF, I don't think one should synthesize one. It is likely to be slow, exactly what you don't want in a two edge FF.

-- glen

Reply to
glen herrmannsfeldt
Loading thread data ...

I agree wholeheartedly, Xilinx should not produce incorrect results, without an error message. Either do it right, or don't do it (stop with error).

Andy

Reply to
Andy

The following double edge flop implementation avoids potential glitches on the output (after all, it is supposed to act like a register). Not all synthesis tools support the single process style, but it can easily be split into two clocked processes and a concurrent assignment.

process (clk, rst) is variable qr,qf : std_logic; begin if rst = '1' then qr := '0'; qf := '0'; elsif rising_edge(clk) then qr := d xor qf; elsif falling_edge(clk) then qf := d xor qr; end if; q

Reply to
Andy

of

on

be

synthesized

I'm

The only trouble is that this is not at all equivalent to the code I wrote. This code is describing two registers with two separate inputs and two separate outputs that are then XORed together. How is this like a register that is clocked on both edges of the clock?

Reply to
rickman

Yes, I was forgetting that "little" issue.

I agree. This is the sort of thing that is very hard to find in a design once it gets past your simulation and fails on the real chip. I suppose it would fail in a post route simulation, no?

Yes, I agree with you and I see that my concerns would not valid.

Reply to
rickman

Like this?

formatting link
formatting link

-- Mike Treseler

Reply to
Mike Treseler

Yes. Even though post-route sims are slow, and don't cover timing as well as STA, they almost always find synthesis errors.

This is an important check-off item before releasing an fpga image for system verification. I have not personally run into a synthesis error in nine years, because I tend to use the same style on the same tools, but this example shows, it is possible to hit one. I like to collect corner cases like this one and KJ's list and to evaluate new tools.

Thanks for the soapbox ;)

-- Mike Treseler

Reply to
Mike Treseler

this?

formatting link

I didn't see the xors in the register inputs. This is a nice little trick. I will remember it.

Reply to
rickman

Perhaps you should explain to the makers of discrete delay lines that they are doing the impossible.

If you're referring instead to synthesizing a delay inside a programmable part like FPGA (which you probably did) than I'd say that the most likely reason for lack of delay line primitives in FPGAs has more to do with lack of demand for such a feature than it is any technical issues that can't be resolved in a profitable manner for the suppliers....but that's a business decision, not technical.

In VHDL speak a module would be an entity...but having a double edge flip flop as an entity is about as useful as a D flip flop primitive (i.e. not very much for the designer writing source code).

Instead what is more useful is a known way to reliably write code to perform that function that will work well. The form I chose was deliberately done to demonstrate a technique to that, by simple inspection, can be seen to be functionally equivalent and synthesizable. The better approach for a double edged flop that you'd really like to use in an actual design was demonstrated by Andy and Mike...but as you can see from rickman's misinterpretation it wasn't obvious to him at first glance, whereas my approach was obvious but left him uneasy about using the clock in logic (and rightly so).

Quite possibly true about the speed...but if you're backed into a corner and don't have either a higher speed clock or a PLL you may be forced to make do.

KJ

Reply to
KJ

KJ wrote: (I wrote)

OK, how about long absolute delays. You can delay some nanoseconds, but I can write a 1s delay in verilog. It would take a very large delay line to do that.

There are many things I would like to see added to FPGAs before analog delay lines.

-- glen

Reply to
glen herrmannsfeldt

One other disadvantage of the explicit coding is that you cannot implement it with data types for which XOR (or XNOR) operations are not defined, like enumerated types, records, arrays, integers, etc. at least not without additional code to define the XOR, which may or may not limit further optimization. For example, you can define an XOR operator for an enumerated type, but you must dictate a binary mapping explicitly, rather than letting the synthesis tool figure out the best mapping.

My point is you can infer an SDR register that will store any data type with a simple assignment in a clocked process. It should be that simple with DDR registers too.

Andy

Reply to
Andy

Not to mention that it is usually considered poor form to use delay lines in digital design.

Reply to
Ray Andraka

(snip)

Yes. I did used to see them in DRAM controllers, though.

Also, in NTSC decoders to get the chrominance and luminance signals right. (That isn't a digital design, though.)

-- glen

Reply to
glen herrmannsfeldt

I remember seeing them in DRAM controllers too. That doesn't make it good design though. There were fewer choices then since the DRAM generally ran off the processor clock making it difficult and expensive to get a multiplied clock (PLLs of the day were much slower than the clock rates for DRAM) needed to get clock edges placed at fractional cycle points without using delay lines to generate those clocks. The better DRAM designs used the delay line to generate a delayed clock rather than delaying memory signals.

Reply to
Ray Andraka

That's one view of it. A more general view is that the 'xor' pair that precedes the flip flops and the 'xor' that does the final combination to produce the outputs perform inverse functions...it just happens that 'xor' is a function that is its own functional inverse. With this more general view of it as performing some function that has an exact inverse function, one could instead use integers or reals as the 'd', 'q' signals (as well as integers or reals for the 'qr' and 'qf' variables) and have a double edge entity for integers or reals as well (code for integers is posted at the end of this posting) and it synthesizes just fine with Quartus (for integers). You use the "-" operator to replace the 'xor' feeding the registers and the "+" operator to replace the 'xor' that combines the register results into the final result.

The 'xor' is an operator that only applies to boolean logic signals whereas "+" and "-" are operators that work with numbers. Obviously "+" and "-" are inverse functions of each other so they meet the minimum criteria. Another criteria has to do with closed loop system stability (switch the usage "+" and "-" and watch the simulation oscillate). This is why the "-" is applied prior to the register and the "+" to compute the final output. In a sense the "-" compuation is computing a difference signal in a form like is routinely done in a closed loop control system.

The nice thing on this example is that it clearly demonstrates the different roles that 'xor' is really playing where it computes the final output as opposed to its role in computing the register inputs. The reason you can't apply this technique to enumerated types and records and such is because there are no mathematical operators that apply to these types....but there are mathematical operators for numbers as well as booleans. It's the lack of mathematical operators that is the problem, not any sort of limitation in the language or boolean logic.

I'm not seeing any reason why this would be of any practical use though. On the rare instances where I've needed to sample on rising and falling edges it's been because of the timing of some part that is external to the FPGA/CPLD. In those rare situations, the critical timing path runs right up to the input of those registers. If the inputs are simply brought right in, they can always be placed in a flop in the IOB which minimizes any min/max differences in the delay from the input pin to the 'D' input of the flop. Inserting any logic (like the 'xor') forces it out of the IOB and increases not only the delay from the pin to the 'D' input of the flip flop, but more importantly, the uncertainty increases as well (i.e. the difference between Tsu(min) and Tsu(max)) which makes timing verification more difficult.

I've never run across the situation where an internal interface to the FPGA required using both edges. If it did, the interface is the problem, it should be widened. Given that, one can reason that it is not very likely that one would ever want double edge flops anyplace except at the I/O pins of the device....and those I/O pins in any practical design are not going to be records or enumerated types....they are mostly std_logic(_vector).

Kevin Jennings

================ Synthesizable code that performs rising/falling edge sampling of an integer.

Blatently based on (OK copied from) Mike Tresler's posting earlier in this thread which used std_logic for 'd' and 'q'.

library ieee; use ieee.std_logic_1164.all;

entity double_edge_integer is generic (vec_len : positive := 8); port ( clk : in std_ulogic; rst : in std_ulogic; d : in integer; q : out integer );

end entity double_edge_integer;

---------------------------------------------- architecture synth of double_edge_integer is begin

double_edge : process (clk, rst) is variable qr, qf : integer; begin if rst = '1' then qr := 0; qf := 0; elsif rising_edge(clk) then qr := d - qf; elsif falling_edge(clk) then qf := d - qr; end if; q

Reply to
KJ

Hmmm....at the start of paragraph you imply that the usage of delay lines in DRAM controllers is not 'good design' but later on go on to say that the 'better DRAM designs' used them.....

KJ

Reply to
KJ

All line encodings are a little mysterious. NRZI, Manchester, HDLC etc.

Yes. It's the line encoding trade-off. I add local logic to save on long distance wires or pins. HDLC instead of start/stop controls. RAS, CAS instead of separate buses PCI express pairs instead of PCI buses. etc.

Which was quietly pasted from Andy's posting ;)

-- Mike Treseler

Reply to
Mike Treseler

Basically, I am saying that if delay lines are used at all in a logic design, they should only be used in the clock generation to generate delayed or out of phase clocks that are used by the rest of the logic. With modern FPGAs, that use of delays is not necessary because the ability to phase shift and/or multiply clocks is built into the FPGA's clock manager circuitry. More often than not, when folks are asking about how to synthesize a delay, it is a delay they are trying to add to their logic rather than to a clock circuit. It is that use of a delay line that I was saying is poor form.

There were some cheap DRAM designs around that inserted logic as a delay on various signals rather than using a delay line to produce an out of phase clock. If you are going to use a delay, it should be used in the clocking logic to produce a delayed clock that is then used by all the logic rather than inserting delays on signal lines to delay those signals. What I was saying is the better designs among those DRAM designs that used delay lines used them to generate a delayed clock rather than to directly delay signals. With modern clock multiplication circuitry, there is little excuse for delay lines in user designs.

Reply to
Ray Andraka

Kevin,

Nice work! I had not thought of the problem as inverse operation pairs, but simply as operators for which there was no value of one argument such that the other argument did not still have control of the output; AND, OR, and their derivatives fail that test.

Interesting also that, for a single bit, the + and - both reduce to XOR, but for multiple bits the bitwise XOR/XNOR is more efficient, since there is no serial propagation.

The result would not always work for reals, since + and - are not always inverse (i.e. if d is small enough relative to qr that qf = d + qr = qr, then qf - qr would be 0, and not d). Therefore the immediate dynamic range of the registered value would be limited artificially.

Similarly, true "integer" arithmetic would fail when the range limits were exceeded in qr or qf. You could pad the ranges of the two registers to accommodate. However, if we assume finite "vector-based" arithmetic (that rolls over) then it would work fine without extending the range. On the other hand, vectors already have XOR defined for them...

Andy

Reply to
Andy

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.