0
\$\begingroup\$

I write a VHDL code for an adder tree, with a parametrized number of vector. It's only for Learning purpouse, so I dind't implemented the carry between the block, I simple created a larger bus so I haven't theme.

I created the internal signal adders_intern, and I created the shown algorithm. To explain it, I attach the immage with the adder tree (sorry for the quality).

Each number represent a signal in the adders_intern vector. So, in the example of the image, related to the algorithm, in the first stage the number of signal is odd so I do I(6) = I(0)+I(1), I(7)=I(2)+I(3) etc. In the second stage I do I(9) = I(6)+I(7), but in this case the number of signals is odd so the last signal is ported as is, so I(10 = I(8), and then I go to the next stage.

This bheavior is generalized for a number of signals equal to M. I check many times the algorithm, it seems correct, but the RTL add only the first two signals, and I don't know why. Here is the code (only the process) :

    process (shifter_out)
        variable  x,f,k : integer ;
        begin
        for i in 0 to M-1 loop
            adders_intern(i) <= shifter_out(i);
        end loop;

        x := M; 
        k :=0;
        while ( (x-k)/2 > 0) loop
                    if (  (x-k) mod 2 = 0)  then -- even case   
                                     for i in x to x+((x-k)/2)-1 loop 
                                           adders_intern(i) <=std_logic_vector( to_unsigned( ( to_integer(unsigned( adders_intern(k))) + to_integer(unsigned(adders_intern(k+1))) ), (M+N) )   ); 
                                           k :=k+2;
                                           f:=i;

                                     end loop;
                    k := k+2; 
                    x :=f+1; -- next value of x                
                    else             -- odd case
                                     for i in x to x+((x-k)/2)-1 loop   
                                           adders_intern(i) <=std_logic_vector( to_unsigned( ( to_integer(unsigned( adders_intern(k))) + to_integer(unsigned(adders_intern(k+1))) ), (M+N) )   ); 
                                           k :=k+2; 
                                           f:=i; 
                                     end loop;    
                    adders_intern(f+1) <= adders_intern(k); -- finalization, for the odd case.
                    x := f+2;
                    k := k+1;
                    end if;
        end loop;
outp <= adders_intern(f-1); -- the last sum is stored in the output
end process;

I'm wrong something in the algorithm, or VHDL don't permit the description of this type of sctructure trough a process?

EDIT : I understand that it can't be made by a process, because process describe the bheavior, not how the interconnections should be wired. But now I was wondering if it is possible to do it with the "generate" statements. I see some paper on the internet that use "generate", with nested for statements, to do the inverse of the tree that I want to make (from one element to multiple elements, balanced tree. I want to make: from multiple elements to one element). So I tried to do it with generate and some variable, used in the same way of the code I used in the process. But of course I got errors because I can't use variables outside the processes. I tried also to find out a clever way to manipulate the index and achieve the gol, but nothing seems to work.

\$\endgroup\$
2
\$\begingroup\$

IEEE Std 1076-2008 3. Design entities and configurations, 3.1 General, paragraphs 2 and 3:

A design entity may be described in terms of a hierarchy of blocks, each of which represents a portion of the whole design. The top-level block in such a hierarchy is the design entity itself; such a block is an external block that resides in a library and may be used as a component of other designs. Nested blocks in the hierarchy are internal blocks, defined by block statements (see 11.2).

A design entity may also be described in terms of interconnected components. Each component of a design entity may be bound to a lower-level design entity in order to define the structure or behavior of that component. Successive decomposition of a design entity into components, and binding those components to other design entities that may be decomposed in like manner, results in a hierarchy of design entities representing a complete design. Such a collection of design entities is called a design hierarchy. The bindings necessary to identify a design hierarchy can be specified in a configuration of the top-level entity in the hierarchy.

Hierarchy (structure) is conveyed by internal or external blocks (block statements, or instantiated components or entities). Noting you can declare signals in concurrent generate statements you could use generate statements in the description of you're algorithm, which would produce block statements.

11.2 Block statement, para 1:

A block statement defines an internal block representing a portion of a design. Blocks may be hierarchically nested to support design decomposition.

(And design decomposition means breaking down the design into smaller pieces here).

A process statement doesn't confer hierarchy:

11.3 Process statement, para 1:

A process statement defines an independent sequential process representing the behavior of some portion of the design.

A process statement conveys behavior in sequential statements, which won't likely match what's synthesized. It's a behavioral description not structural.

An elaborated model (14. Elaboration and execution) preserves hierarchy in block statements.

14.2 Elaboration of a design hierarchy, para 5:

Elaboration of a design hierarchy defined by a design entity consists of the elaboration of the block statement equivalent to the external block defined by the design entity. The architecture of this design entity is assumed to contain an implicit configuration specification (see 7.3) for each component instance that is unbound in this architecture; each configuration specification has an entity aspect denoting an anonymous configuration declaration identifying the visible entity declaration (see 7.3.3) and supplying an implicit block configuration (see 3.4.2) that binds and configures a design entity identified according to the rules of 7.3.3. The equivalent block statement is defined in 11.7.3. Elaboration of a block statement is defined in 14.5.2.

14.5.2 Block statements

Elaboration of a block statement consists of the elaboration of the block header, if present, followed by the elaboration of the block declarative part, followed by the elaboration of the block statement part.

An elaborated design model is used as the basis for both simulation and synthesis - the latter not described in the VHDL standard.

So the later conjecture in your question is more accurate, that a VHDL process doesn't convey structure (hierarchy). A process statement describing behavior is subject to logic reduction, and primitive mapping but imposes no hierarchy, which requires ports (signals).

And for practical purposes you can infer post synthesis structure in a process through the use of sequential logic (latches, registers), while combinational logic (processes without a clock edge or wait statement) only have two categories of defined structures - asynchronous ROMs and RAMs.

See IEEE Std 1076.6-2004 (now withdrawn), 6. Modeling hardware elements, paras 1 and 2:

This clause specifies styles for modeling hardware elements such as edge-sensitive storage elements, level-sensitive storage elements, three-state elements, and combinational elements.

This clause does not limit the optimizations that can be performed on a VHDL model. The scope of optimizations that may be performed by a synthesis tool depends on the tool itself. The hardware modeling styles specified in this clause do not take into account any optimizations or transformations. A specific tool may perform optimizations; this may result in removal of redundant or unused logic from the final netlist. This shall NOT be taken as a violation of this standard provided the synthesized netlist has the same functionality as the input model, as characterized in Clause 5.

(Also see the various subclauses.)

A combinational logic process has few hints useful in describing structure and the hardware actually produced isn't otherwise under your control.

There may also synthesis target specific inferences that can be made based on the use of statements (e.g. procedure calls), operators, expressions and numbers of bits (array length). The ability to do that is beyond the scope of VHDL language and the now withdrawn RTL Synthesis standard. The ability to convey structure in this manner is inherently non portable.

\$\endgroup\$
  • \$\begingroup\$ Ok, all is clear but I still have a doubt about your last sentence. You said that we have no control over the RTL sctructure generated by VHDL, and it is beyonde the scope of VHDL itself. But I see that many projects implement various type of the same function but with differente structure, for example the adders or the multipliers can be implemented with various algorithms, more or less efficient (wallace tree etc), and we describe differently the VHDL code to obtain the RTL for the relative algorithm, so I can't point out your last sentence \$\endgroup\$ – Daniele Apr 18 '16 at 7:20
  • 1
    \$\begingroup\$ And a Wallace Tree multiplier isn't described with a "*" multiplying operator. You can in trust synthesis to give you hardware that meets your constraints (or tell you if it fails). The clause 6. of the IEEE Std 1076.6-2004 shown above. The more detail you provide the harder synthesis tools will have to work to overcome your design description to do 'the right thing' for the target platform. \$\endgroup\$ – user8352 Apr 19 '16 at 3:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.