Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL: writing codes that have smallest footprint on FPGAs

Status
Not open for further replies.

tahirsengine

Member level 3
Joined
May 7, 2007
Messages
66
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,288
Location
Germany
Activity points
1,929
Hi,
I wanted to create this thread to gather information about the syntax of VHDL that yields the smallest circuitry in synthesis.
Now, as we know that the best way to write codes that yields the smallest circuitry in Synthesis is through library functions. The worst part of these codes comes when you want to port the same code on different FPGA(i.e from Xilinx to Altera).
That mean such codes should be generic so that these can easily be ported towards other platforms.

If you know some of such techniques in VHDL, that produces least circuitry after synthesis then it will be of great value(across different platforms) i.e As I know that if else statement produces more circuitry than ternary operator in Verilog. Similarly, default value in Case structure invokes memory elements, and thus produces more circuitry. But these examples are from Verilog. Want to know such techniques in VHDL.

Please share your knowledge, any link or document on this topic.

Regards
Tahir
 

There is no one answer to this, as each application will be different. But I would argue most of your assertions are wrong.

Using library primitives is definitely not the best approach for the smallest option. Unless you are good with placing gates you may restrict optimisations available in the synthesis optimisations. Plus unless you have an optimal solution drawn out, it isn't necessarily optimal. And it will be terrible for any other engineers to pick up.

Also, a deafault in a case statement won't always produce a memory element, it depends on the code. Same with an others choice in vhdl, it is situational.

If else isn't necessarily worse than if else, it can produce the same circuit.

For any language, the best code is one that is well documented and can easily be picked up by another engineer. Id I would always choose this over a highly optimized but difficult to understand design (these designs are usually the least flexible and often get scrapped when changes are needed)
 
There is no one answer to this, as each application will be different. But I would argue most of your assertions are wrong.

Using library primitives is definitely not the best approach for the smallest option. Unless you are good with placing gates you may restrict optimisations available in the synthesis optimisations. Plus unless you have an optimal solution drawn out, it isn't necessarily optimal. And it will be terrible for any other engineers to pick up.

Also, a deafault in a case statement won't always produce a memory element, it depends on the code. Same with an others choice in vhdl, it is situational.

If else isn't necessarily worse than if else, it can produce the same circuit.

For any language, the best code is one that is well documented and can easily be picked up by another engineer. Id I would always choose this over a highly optimized but difficult to understand design (these designs are usually the least flexible and often get scrapped when changes are needed)

So what to do when you badly need to save the space on FPGA?
 

Modify the code to reduce resource usage. How this is done will be dependent on the design. Often it may require removing whole blocks.
 

i.e As I know that if else statement produces more circuitry than ternary operator in Verilog. Similarly, default value in Case structure invokes memory elements, and thus produces more circuitry. But these examples are from Verilog.

This is absolutely not true.
 

I would argue that generally the ternary operator produce less circuitry than if-else. This happens because the ternary operator always require the "else" (or :), while one can skip the else when using if-else statements.

An alone "if" instruction may be implemented as a enable or other weird optimizations, while "if-else" or "?:" are usually implemented as flip-flops or mux. Not that using a "if" as enable is always a bad thing, but it may generate a bigger circuit depending of utilization.

Other point to argue is that ternary operator usually is easier to optimize (visually speaking) than if-else statements.
 

Makes no sense. You must compare apples to apples. the example below is logically equivalent.

Code:
a = (cond) ? 0 : 1;

if (cond)
 a = 0;
else
a = 1;
 

Yes, but when you have a chain of "if-else", they can be different.

For example, the codes below produces the same result, but produces a different circuit:

Code:
if (cond == 1'b1)
begin
  if (b == 3'b000)
    a <= c;
  else if (b == 3'b001 && s == 1'b0)
    a <= c+1;
  else if (b == 3'b001 && s == 1'b1)
    a <= c-1;
  else if (b == 3'b010)
    a <= 0;
  else if (b == 3'b011 && s == 1'b0)
    a <= c+d;
  else if (b == 3'b011 && s == 1'b1)
    a <= c-d;
  else if (b == 3'b100)
    a <= c*d;
end

Use ternary op, one possibility is to describe the same is:

Code:
a <= cond == 1'b1 ? b == 3'b000 ? c             :
                    b == 3'b001 ? s ? c-1 : c+1 :
                    b == 3'b010 ? 0             :
                    b == 3'b011 ? s ? c-d : c+d :
                    b == 3'b100 ? c*d           : a : a;

In this case I found that if-else used less logic, but ternary logic produced was way faster.
 

The problem with if/else is that it implies priority. If you used a case statement you'd probably similar or the same result.

But if I was another engineer taking your code 3 months after you left, I'd delete that ternary description for its terrible lack of clarity. Ternaries inside ternaries won't gain you any respect.
 

I wanted to create this thread to gather information about the syntax of VHDL that yields the smallest circuitry in synthesis.
(... not true sentences ...)
If you know some of such techniques in VHDL, that produces least circuitry after synthesis then it will be of great value(across different platforms)
(... more not true sentences ...)

Please share your knowledge, any link or document on this topic.

In general every design is different and must be analysed separately in case of generation the smallest circuitry.
I would suggest to focus on functions that the design must do and write your own RTL description tailored for your needs.
Do you need all the functionality that some large "of the shelf" IP Core provide or you need only some part of it? If we talk about the smallest circuitry, then maybe the only way would be to write your own RTL description of that smaller part.

Another factor is to follow vendor recommendations. Find and read appropriate user guides.

Of course the synthesis tool is another factor. You could compare results of the ISE/Vivado, Synplify from Synopsys and Quartus from Altera and pick the smallest circuit for the implementation step.
 

In general every design is different and must be analysed separately in case of generation the smallest circuitry.
I would suggest to focus on functions that the design must do and write your own RTL description tailored for your needs.
Do you need all the functionality that some large "of the shelf" IP Core provide or you need only some part of it? If we talk about the smallest circuitry, then maybe the only way would be to write your own RTL description of that smaller part.

Another factor is to follow vendor recommendations. Find and read appropriate user guides.

Of course the synthesis tool is another factor. You could compare results of the ISE/Vivado, Synplify from Synopsys and Quartus from Altera and pick the smallest circuit for the implementation step.

I am using Vivado to write and test my designs. So, how to compare my design results with Quartus or Synplify, as the target FPGA is also Xilinx FPGA(Zynq 7 series)?

- - - Updated - - -

Guys,
I appreciate your responses. Please be focused on VHDL.

Thanks and cheers
Tahir
 

So, how to compare my design results with Quartus or Synplify, as the target FPGA is also Xilinx FPGA(Zynq 7 series)?
You need to get the necessary tools for comparison.
When the various tools have generated the synthesis report, look there in and compare the amount of LUT* (For Xilinx 7 series FPGA, * = 1..6) used in each case as a *basic* comparison.
 
Yes, but when you have a chain of "if-else", they can be different.

For example, the codes below produces the same result, but produces a different circuit:

Code:
if (cond == 1'b1)
begin
  if (b == 3'b000)
    a <= c;
  else if (b == 3'b001 && s == 1'b0)
    a <= c+1;
  else if (b == 3'b001 && s == 1'b1)
    a <= c-1;
  else if (b == 3'b010)
    a <= 0;
  else if (b == 3'b011 && s == 1'b0)
    a <= c+d;
  else if (b == 3'b011 && s == 1'b1)
    a <= c-d;
  else if (b == 3'b100)
    a <= c*d;
end

Use ternary op, one possibility is to describe the same is:

Code:
a <= cond == 1'b1 ? b == 3'b000 ? c             :
                    b == 3'b001 ? s ? c-1 : c+1 :
                    b == 3'b010 ? 0             :
                    b == 3'b011 ? s ? c-d : c+d :
                    b == 3'b100 ? c*d           : a : a;

In this case I found that if-else used less logic, but ternary logic produced was way faster.

As noted above, these are not the same because of priority. My point still stands, you don't get better circuits from ternary operator. You could achieve the same with parallel ifs or a case statement. Don't blame the language when you misuse it.
 

As noted above, these are not the same because of priority.
At first sight, both codes implement the same priority. Also, priority only matters for not fully decoded or non-unique input conditions. In the present case, there are only some undecoded combinations, they either generate a latch (combinational) or keeping the previous registered state, identical in both cases as far as I see.

Apart from this slightly sophistic consideration, I completely agree with all statements for using the clearest, most readable coding style.
 

Why using a language artifice is a misuse?

Because ternary operator is unusual, it means automatically it is wrong? Sorry to disagree with this. While I fully understand that people don't like to read it (mainly because they are not used to), but the use of ternaries cannot be defined as wrong or misuse by any means.

Yes, a case could be used in the case above to produce the same circuit, but my focus was to illustrate a difference between "if-else" and ternary. There are cases where "case" cannot be used - for example, when you have different selector signals on MUX.

Ternary is a very powerful operator, that usually provides a faster circuit, and people usually ignores it simply because they do not like to read it.
 

Ternary is a very powerful operator, that usually provides a faster circuit, and people usually ignores it simply because they do not like to read it.
"Faster" sounds unsubstantiated. Modern synthesis tools generate equal gate level circuits for functionally equivalent HDL code (e.g. ternary versus if else) in most cases. Nobody said that ternary operator is wrong, but tends to make code less readable.

I feel that the discussed coding style question is only a minor point for effective FPGA usage. Design structure, algorithms, clocking and pipelining are much more important.
 

There is nothing wrong with the ternary operator. Using it as you did may even meet the op's goals of reducing logic. But our point is that while this may be the case (although in all languages, there is usually at least 2 ways to do the same thing) even if you you do improve logic use, if it is hard for others to understand, your effort may be for nothing in the larger scheme of things if no one bothers to use it. In industry, crap code is crap code, no matter how clever it is. Just because you're clever, no one likes a smart arse, and if someone doesn't understand it, they won't use it, and nothing is learned. No matter how clever you are or think you are.

For stuff to stick, and others to learn, it has to be clever code that is also understandable by someone with less skill than yourself.
 
  • Like
Reactions: asdf44

    asdf44

    Points: 2
    Helpful Answer Positive Rating
Ternary is a very powerful operator, that usually provides a faster circuit, and people usually ignores it simply because they do not like to read it.

I will try again.

There is nothing faster about the ternary operator. Claiming so is naive, and the example you have shown is not a good one.
 

For stuff to stick, and others to learn, it has to be clever code that is also understandable by someone with less skill than yourself.

I'd suggest just using this as the definition of clever.


Echoing some comments above...syntax is basically irrelevant. HDL code describes actual hardware and it's the design of that hardware which dictates performance. Good code is clear code and clear code will be easily understood by both humans and synthesizers leading to good and predictable performance.

Asking about syntax specifically is like asking how to draw a circuit differently to reduce BOM cost...it doesn't make much sense.


There are some arguments to be had about synchronous resets vs asynchronous resets and impact on performance...but that's a design discussion not a syntax one.
 

The biggest place you can save logic is by understanding the problem and the requirements and then selecting good architecture choices. I don't think there is a "design patterns" equivalent for FPGAs. But such a thing would be great.

For example, one design I saw had a network processor. Later, multiple channels were needed. So multiple modules were instantiated and some input/output arbitration was added outside these instances. This was even though other code would look up the channel state from small RAMs and then have only 1 FSM for all channels. The network processors also attempted to do all processing as if it needed to be done in 1 cycle, even though most processing was only needed once per packet. But don't worry, the modules had custom (undocumented) interfaces that saved some resources by not keeping the pipelined signals aligned if they didn't need to be.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top