Added Ortree maybe

This commit is contained in:
Greatorex 2022-02-21 16:59:47 +01:00
parent df97903436
commit b076513813
1 changed files with 59 additions and 37 deletions

View File

@ -34,6 +34,9 @@ namespace tmpl {
export deftype power (bool?! vdd, vss) { }
export template<pint N; pbool invert>
defproc ortree (bool? in[N]; bool out)
{
@ -43,14 +46,48 @@ defproc ortree (bool? in[N]; bool out)
pint i, end, j;
pbool isinv;
isinv = false;
isinv = invert;
i = 0;
end = N-1;
/* dynamic array that holds all the nodes in the completion tree */
bool tmp[N];
pint lenTree2Count, lenTree3Count;
/* Pre"calculate" the number of C cells required, look below if confused */
*[ i != end ->
j = 0;
*[ i < end ->
j = j + 1;
[ i+1 >= end ->
i = end;
lenTree2Count = lenTree2Count +1;
[] i+2 >= end ->
i = end;
lenTree3Count = lenTree3Count +1;
[] else ->
i = i + 2;
lenTree2Count = lenTree2Count +1;
]
]
/*-- update range that has to be combined --*/
i = end+1;
end = end+j;
j = 0;
]
/* array that holds ALL the nodes in the completion tree */
bool tmp[end];
(k:N:tmp[k] = in[k];)
/* array to hold the actual C-elments, either A2C or A3C */
OR2_X1 C2Els[lenTree2Count];
OR3_X1 C3Els[lenTree3Count];
/* Reset the variables we just stole lol */
i = 0;
end = N-1;
j = 0;
pint tree2Index = 0;
pint tree3Index = 0;
/* Invariant: i <= end */
*[ i != end ->
@ -64,51 +101,36 @@ defproc ortree (bool? in[N]; bool out)
/*-- there are still signals that need to be combined --*/
j = j + 1;
bool tmp[end+j..end+j];
[ i+2 >= end ->
/*-- last piece: use either a 2 or 3 input NAND/NOR gate --*/
[isinv ->
prs { (&k:i..end:tmp[k]) => tmp[end+j]- }
[] else ->
prs { (|k:i..end:tmp[k]) => tmp[end+j]- }
]
[ i+1 >= end ->
/*-- last piece: use either a 2 input C-element --*/
C2Els[tree2Index].c1 = tmp[i];
C2Els[tree2Index].c2 = tmp[i+1];
C2Els[tree2Index].y = tmp[end+j];
tree2Index = tree2Index +1;
i = end;
[] i+2 >= end ->
/*-- last piece: use either a 3 input C-element --*/
C3Els[tree3Index].c1 = tmp[i];
C3Els[tree3Index].c2 = tmp[i+1];
C3Els[tree3Index].c3 = tmp[i+2];
C3Els[tree3Index].y = tmp[end+j];
tree3Index = tree3Index +1;
i = end;
[] else ->
/*-- more to come; so use a two input C-element --*/
[isinv ->
prs { (&k:i..i+1:tmp[k]) => tmp[end+j]- }
[] else ->
prs { (|k:i..i+1:tmp[k]) => tmp[end+j]- }
]
C2Els[tree2Index].c1 = tmp[i];
C2Els[tree2Index].c2 = tmp[i+1];
C2Els[tree2Index].y = tmp[end+j];
tree2Index = tree2Index +1;
i = i + 2;
]
sizing {
leak_adjust <- 1;
p_n_mode <- 1;
tmp[end+j]{-1}
}
]
/*-- we just added an inverting layer --*/
isinv = ~isinv;
/*-- update range that has to be combined --*/
i = end+1;
end = end+j;
j = 0;
]
isinv = invert ? ~isinv : isinv;
/*-- invert the signal if needed --*/
[isinv -> prs { tmp[end] => out- }
[] else -> tmp[end] = out;
]
[isinv ->
sizing {
leak_adjust <- 1;
p_n_mode <- 1;
out{-1}
}
]
}
/*