From b0765138132985f684cd03694d2eca2f897f32a3 Mon Sep 17 00:00:00 2001 From: Hugh Date: Mon, 21 Feb 2022 16:59:47 +0100 Subject: [PATCH] Added Ortree maybe --- dataflow_neuro/treegates.act | 96 ++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 37 deletions(-) diff --git a/dataflow_neuro/treegates.act b/dataflow_neuro/treegates.act index c839c69..0d9ce1d 100644 --- a/dataflow_neuro/treegates.act +++ b/dataflow_neuro/treegates.act @@ -34,6 +34,9 @@ namespace tmpl { export deftype power (bool?! vdd, vss) { } + + + export template 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} - } - ] } /*