continued handshaking tree, not finished

This commit is contained in:
Michele 2022-03-02 18:38:17 +01:00
parent b49b9d98c3
commit 3e1b63c201
1 changed files with 105 additions and 90 deletions

View File

@ -509,103 +509,118 @@ namespace tmpl {
// A tree composed by arbiters. The first layer takes N signals // A tree composed by arbiters. The first layer takes N signals
export template<pint N> export template<pint N>
defproc arbiter_tree(a1of1 in[N],a1of1 out; power supply) defproc arbiter_tree(a1of1 in[N]; a1of1 out; power supply)
{ {
bool tout; bool tout;
{ N > 0 : "What?" }; { N > 0 : "Invalid N, should be greater than 0" };
/* We calculate here how many elements we need to create the full tree */ /* We calculate here how many arbiters we need to create for the full tree */
pint i, end, j; pint inputs_in_layer, end, elements_in_layer;
i = 0; pint odd_element_idx = 0;
pint odd_element_flag = 0;
inputs_in_layer = 0;
end = N-1; end = N-1;
pint element_counter = 0;
pint lenTree2Count, lenTree3Count; // Here we start a for loop to count the elements in the tree
pint odd_one_idx = 0; // The loop iterates for every successive layer
pbool odd_one_flag = 0; // i is the variable used to iterate the inputs,
lenTree2Count = 0; // j counts the elements in the layer
*[ i != end -> *[ inputs_in_layer != end ->
j = 0; elements_in_layer = 0; // At every layer the counter of the elements is resetted
*[ i < end -> *[ inputs_in_layer < end ->
j = j + 1; [ inputs_in_layer + 1 >= end ->
[ i+1 >= end -> //In this case, the number of input is even: the layer finishes
i = end; inputs_in_layer = end;
lenTree2Count = lenTree2Count +1; odd_element_flag = 0;
[] inputs_in_layer + 2 >= end ->
[] i >= end -> //In this case, we arrived at the last input, this means the inputs are odd
i = end; //We need to save the odd input index and move it to the next layer,
odd_one_idx = i; //up to when the resulting number is even
odd_one_flag = 1; odd_element_idx = end;
odd_element_flag = 1;
inputs_in_layer = end;
[] else -> [] else ->
i = i + 2; //If we are not close to the end, analyzes the next two inputs
lenTree2Count = lenTree2Count +1; inputs_in_layer = inputs_in_layer +2;
] ]
] elements_in_layer = elements_in_layer + 1; //At every step the elements count is updated
/*-- update range that has to be combined --*/
i = end+1;
end = end+j+odd_one_flag;
]
/* array that holds ALL the wires in the completion tree */
a1of1 wire[end+1];
// Connecting the first nodes to the input
(l:N:
wire[l] = in[l];
)
[lenTree2Count > 0 ->
arbiter_handshake arb_array[lenTree2Count];
]
(h:lenTree2Count:arb_array[h].vdd = supply.vdd;)
(h:lenTree2Count:arb_array[h].vss = supply.vss;)
/* Reset the variables before the assigmnent of the nodes to the cells */ ]
i = 0; //Move the inputs_in_layer to the next layer
//Increase the end to account for the next layer elements
//If there was an odd element, count it also in the end
inputs_in_layer = end + 1;
end = end + elements_in_layer + odd_element_flag;
element_counter = element_counter + elements_in_layer;
]
{ element_counter = 4 : "Michele you did wrong" };
// Creating the elements of the tree
arbiter_handshake arb_array[element_counter];
(i:element_counter:arb_array[i].supply = supply;)
// These are the wires that connect one element of the tree to the others
a1of1 channels[element_counter*2];
//Connecting the first channels to the inputs
(i:N:channels[i] = in[i];)
channels[element_counter*2-1] = out;
//Now we redo the for loop but here to assign the channels to the elements
odd_element_idx = 0;
odd_element_flag = 0;
inputs_in_layer = 0;
end = N-1; end = N-1;
j = 0; { end=4 : "Michele you did wrong" };
pint tree2Index = 0; // Here we start a for loop to count the elements in the tree
pint tree3Index = 0; // The loop iterates for every successive layer
*[ i != end -> // i is the variable used to iterate the inputs,
/* // j counts the elements in the layer
* Invariant: tmp[i..end] has the current signals that need to be *[ inputs_in_layer != end ->
* combined together, and "isinv" specifies if they are the inverted elements_in_layer = 0; // At every layer the counter of the elements is resetted
* sense or not *[ inputs_in_layer < end ->
*/ [ inputs_in_layer + 1 >= end ->
j = 0; //In this case, the number of input is even: the layer finishes
*[ i < end -> [ odd_element_flag >= 1 ->
/*-- there are still signals that need to be combined --*/ arb_array[elements_in_layer].in1 = channels[inputs_in_layer];
j = j + 1; arb_array[elements_in_layer].in2 = channels[odd_element_idx];
[ i+1 >= end ->
/*-- last piece: use either a 2 input C-element --*/
C2Els[tree2Index].a = wire[i];
C2Els[tree2Index].b = wire[i+1];
C2Els[tree2Index].y = wire[end+j];
tree2Index = tree2Index +1;
i = end;
[] i+2 >= end ->
/*-- last piece: use either a 3 input C-element --*/
C3Els[tree3Index].a = tmp[i];
C3Els[tree3Index].b = tmp[i+1];
C3Els[tree3Index].c = tmp[i+2];
C3Els[tree3Index].y = tmp[end+j];
tree3Index = tree3Index +1;
i = end;
[] else -> [] else ->
/*-- more to come; so use a two input C-element --*/ arb_array[elements_in_layer].in1 = channels[inputs_in_layer];
C2Els[tree2Index].a = tmp[i]; arb_array[elements_in_layer].in2 = channels[inputs_in_layer+1];
C2Els[tree2Index].b = tmp[i+1];
C2Els[tree2Index].y = tmp[end+j];
tree2Index = tree2Index +1;
i = i + 2;
] ]
inputs_in_layer = end;
odd_element_flag = 0;
[] inputs_in_layer + 2 >= end ->
//In this case, we arrived at the last input, this means the inputs are odd
//We need to save the odd input index and move it to the next layer,
//up to when the resulting number is even
odd_element_idx = end;
odd_element_flag = 1;
{ end<8 : "Michele you did wrong" };
{ odd_element_idx=4 : "Michele you did wrong" };
arb_array[elements_in_layer].in1 = channels[inputs_in_layer];
arb_array[elements_in_layer].in2 = channels[inputs_in_layer+1];
inputs_in_layer = end;
[] else ->
//If we are not close to the end, analyzes the next two inputs
arb_array[elements_in_layer].in1 = channels[inputs_in_layer];
arb_array[elements_in_layer].in2 = channels[inputs_in_layer+1];
inputs_in_layer = inputs_in_layer +2;
] ]
/*-- update range that has to be combined --*/ elements_in_layer = elements_in_layer + 1; //At every step the elements count is updated
i = end+1;
end = end+j; ]
j = 0; //Move the inputs_in_layer to the next layer
//Increase the end to account for the next layer elements
//If there was an odd element, count it also in the end
inputs_in_layer = end + 1;
end = end + elements_in_layer + odd_element_flag;
element_counter = element_counter + elements_in_layer;
] ]
out = tmp[end];
} }
export template<pint N> export template<pint N>