Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'll try to provide an answer that allows you to build a generic tree, without recursion, based only on the tree height provided as a generic at compile time. The code itself looks a bit tricky for my taste; however, the principles behind the solution are straigthforward. Here's an outline of the solution:</p> <ul> <li>Imagine your nodes will be placed on a grid, with dimensions V=TREE_HEIGHT+1 and H=2**TREE_HEIGHT (see the ASCII-gram below). Then, all you need is an algorithm to populate the grid with nodes, and to make the right input and output connections.</li> <li>To connect one level of the tree to the next, you can use a bidimensional array of size TREE_HEIGHT x 2**TREE_HEIGHT (see line 63 in the code example below).</li> <li>To instantiate the nodes, use two nested loops (<code>for-generate</code> in VHDL, see lines 68-69). You will not populate all nodes; for a given row at depth=<em>i</em>, only 2**(i-1) nodes are needed (line 71).</li> <li>You can instantiate different entities for internal and leaf nodes. Just check whether the current value of <em>i</em> equals TREE_HEIGHT (lines 74 and 84).</li> <li>Finally, you just need to connect the layers of the tree. The arithmetic is a bit tricky, but once you get it right you're done (lines 78-80).</li> <li>Count on your synthesis tool to remove the unused wires.</li> </ul> <p>Here's a poor rendition of the "grid" for HEIGHT=2:</p> <pre><code> j = 1 j = 2 j = 3 j = 4 +---------------+---------------+---------------+---------------+ i = 1 | Root Node | (empty) | (empty) | (empty) | +---------------+---------------+---------------+---------------+ i = 2 | Internal Node | Internal Node | (empty) | (empty) | +---------------+---------------+---------------+---------------+ i = 3 | Internal Node | Internal Node | Internal Node | Internal Node | +---------------+---------------+---------------+---------------+ </code></pre> <p>Here's the code example:</p> <pre><code>/* 1 */ package tree_types_pkg is /* 2 */ -- define a data type for the input and output values at each node /* 3 */ subtype tree_data_type is integer range 0 to 255; /* 4 */ -- define a vector type to propagate the output of a tree level to the next /* 5 */ type layer_to_layer_channel_type is array (natural range &lt;&gt;) of tree_data_type; /* 6 */ end; /* 7 */ -------------------------------------------------------------------------------- /* 8 */ use work.tree_types_pkg.all; /* 9 */ /* 10 */ entity internal_node is /* 11 */ generic ( /* 12 */ TREE_HEIGHT: integer := 3 /* 13 */ ); /* 14 */ port ( /* 15 */ x: in integer range 1 to 2**TREE_HEIGHT; /* 16 */ y: in integer range 1 to TREE_HEIGHT; /* 17 */ input: in tree_data_type; /* 18 */ output_left: out tree_data_type; /* 19 */ output_right: out tree_data_type /* 20 */ ); /* 21 */ end; /* 22 */ /* 23 */ architecture rtl of internal_node is begin /* 24 */ -- perform some calculation at the node /* 25 */ output_left &lt;= input + x * y; /* 26 */ output_right &lt;= input - x * y; /* 27 */ end; /* 28 */ -------------------------------------------------------------------------------- /* 29 */ use work.tree_types_pkg.all; /* 20 */ /* 31 */ entity leaf_node is /* 32 */ generic ( /* 33 */ TREE_HEIGHT: integer := 3 /* 34 */ ); /* 35 */ port ( /* 36 */ x: in integer range 1 to 2**TREE_HEIGHT; /* 37 */ y: in integer range 1 to TREE_HEIGHT; /* 38 */ input: in tree_data_type; /* 39 */ output: out tree_data_type /* 30 */ ); /* 41 */ end; /* 42 */ /* 43 */ architecture rtl of leaf_node is begin /* 44 */ -- perform some calculation at the node /* 45 */ output &lt;= input + x * y; /* 46 */ end; /* 47 */ -------------------------------------------------------------------------------- /* 48 */ use work.tree_types_pkg.all; /* 49 */ /* 50 */ entity dirtybit_binary_tree is /* 51 */ generic ( /* 52 */ TREE_HEIGHT: integer := 4 /* 53 */ ); /* 54 */ port ( /* 55 */ tree_input: in tree_data_type; /* 56 */ tree_outputs: out layer_to_layer_channel_type(1 to 2**TREE_HEIGHT) /* 57 */ ); /* 58 */ end; /* 59 */ /* 60 */ architecture behavior of dirtybit_binary_tree is /* 61 */ constant LEAF_NODES_COUNT: integer := 2**TREE_HEIGHT; /* 62 */ type channel_array_type is array (natural range &lt;&gt;) of layer_to_layer_channel_type; /* 63 */ signal connections: channel_array_type(1 to TREE_HEIGHT)(1 to LEAF_NODES_COUNT); /* 64 */ begin /* 65 */ /* 66 */ connections(1)(1) &lt;= tree_input; /* 67 */ /* 68 */ grid_y: for i in 1 to TREE_HEIGHT generate /* 69 */ grid_x: for j in 1 to LEAF_NODES_COUNT generate /* 70 */ /* 71 */ instantiate_nodes: if j &lt;= 2**(i-1) generate /* 72 */ /* 73 */ internal_nodes: if (i /= TREE_HEIGHT) generate /* 74 */ internal_node: entity work.internal_node /* 75 */ generic map (TREE_HEIGHT =&gt; TREE_HEIGHT) /* 76 */ port map ( /* 77 */ x =&gt; j, /* 78 */ y =&gt; i, /* 79 */ input =&gt; connections(i)(j), /* 80 */ output_left =&gt; connections(i+1)((j-1)*i+1), /* 81 */ output_right =&gt; connections(i+1)((j-1)*i+2) /* 82 */ ); /* 83 */ end generate; /* 84 */ /* 85 */ leaf_nodes: if (i = TREE_HEIGHT) generate /* 86 */ leaf_node: entity work.leaf_node /* 87 */ generic map (TREE_HEIGHT =&gt; TREE_HEIGHT) /* 88 */ port map ( /* 89 */ x =&gt; j, /* 90 */ y =&gt; i, /* 91 */ input =&gt; connections(i)(j), /* 92 */ output =&gt; tree_outputs(j) /* 93 */ ); /* 94 */ end generate; /* 95 */ /* 96 */ end generate; /* 97 */ /* 98 */ end generate; /* 99 */ end generate; /* 100 */ /* 101 */ end; </code></pre> <p>Finally, here's what the synthesized circuit looks like on Quartus 12.1 (RTL Viewer):</p> <p><img src="https://i.stack.imgur.com/TMtfV.png" alt="Tree circuit on Quartus RTL Viewer"></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload