1+ /*************************************************************************
2+ *
3+ * This file is part of ACT standard library
4+ *
5+ * Copyright (c) 2025 Karthi Srinivasan
6+ *
7+ * Licensed under the Apache License, Version 2.0 (the "License");
8+ * you may not use this file except in compliance with the License.
9+ * You may obtain a copy of the License at
10+ *
11+ * http://www.apache.org/licenses/LICENSE-2.0
12+ *
13+ * Unless required by applicable law or agreed to in writing, software
14+ * distributed under the License is distributed on an "AS IS" BASIS,
15+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+ * See the License for the specific language governing permissions and
17+ * limitations under the License.
18+ *
19+ **************************************************************************
20+ */
21+
22+ import std::cells;
23+ import std::gates;
24+
25+ namespace std {
26+
27+ export namespace delay_elements {
28+
29+ // Symmetric Delay Elements -----------------------
30+ export defproc delay_buffer (bool? in; bool! out)
31+ {
32+ std::cells::INVX1 invs[2];
33+ invs[0].A = in;
34+ invs[0].Y = invs[1].A;
35+ invs[1].Y = out;
36+ spec {
37+ timing in+ : out+ < in-
38+ timing in- : out- < in+
39+ }
40+ }
41+
42+ export template <pint L>
43+ defproc weak_delay_buffer (bool? in; bool! out) {
44+ bool x;
45+ prs {
46+ in<1,L> => x-
47+ x<1,L> => out-
48+ }
49+ spec {
50+ timing in+ : out+ < in-
51+ timing in- : out- < in+
52+ }
53+ }
54+ // Symmetric Delay Elements -----------------------
55+
56+ // Asymmetric Delay Elements ----------------------
57+ export template <pint REC, L> defproc fast0_slow1_rec (bool? in; bool! out);
58+
59+ export template <pint REC, L> defproc fast1_slow0_rec (bool? in; bool! out);
60+
61+ export template <pint REC, L>
62+ defproc fast0_slow1_rec (bool? in; bool! out) {
63+ { REC>=0 : "what" };
64+ bool x; bool f0s1out, f1s0out;
65+ [ REC=0 -> f0s1out = in;
66+ f1s0out = x;
67+ []REC>0 -> fast0_slow1_rec<REC-1,L> f0s1r(in); f0s1out = f0s1r.out;
68+ fast1_slow0_rec<REC-1,L> f1s0r(x); f1s0out = f1s0r.out;
69+ ]
70+ prs {
71+ [keeper=0] f0s1out<1,L> & in<1,1> -> x-
72+ [keeper=0] ~in<1,1> -> x+
73+ [keeper=0] x<1,1> -> out-
74+ [keeper=0] ~f1s0out<1,L> & ~x<1,1> -> out+
75+ }
76+ spec {
77+ timing in+ : out+ < in-
78+ timing in- : out- < in+
79+ }
80+ }
81+
82+ export template <pint REC, L>
83+ defproc fast1_slow0_rec (bool? in; bool! out) {
84+ { REC>=0 : "what" };
85+ bool x; bool f0s1out, f1s0out;
86+ [ REC=0 -> f1s0out = in;
87+ f0s1out = x;
88+ []REC>0 -> fast1_slow0_rec<REC-1,L> f1s0r(in); f1s0out = f1s0r.out;
89+ fast0_slow1_rec<REC-1,L> f0s1r(x); f0s1out = f0s1r.out;
90+ ]
91+ prs {
92+ [keeper=0] in<1,1> -> x-
93+ [keeper=0] ~f1s0out<1,L> & ~in<1,1> -> x+
94+ [keeper=0] f0s1out<1,L> & x<1,1> -> out-
95+ [keeper=0] ~x<1,1> -> out+
96+ }
97+ spec {
98+ timing in+ : out+ < in-
99+ timing in- : out- < in+
100+ }
101+ }
102+
103+ export defproc reuse_1 (bool? in; bool! out; bool! dl_in; bool? dl_out) {
104+ std::cells::XOR2X1 xor;
105+ bool a, b, _i;
106+ _i = xor.A;
107+ a = xor.B;
108+ xor.Y = dl_in;
109+ b = dl_out;
110+ prs {
111+ b & in #> a-
112+ a -> out-
113+ ~a & ~b -> out+
114+ in => _i-
115+ }
116+ spec {
117+ timing in+ : out+ < in-
118+ timing in- : out- < in+
119+ }
120+ }
121+
122+ export defcell PCELEM2 (bool? A, B; bool! Y) {
123+ bool _Y;
124+ prs {
125+ A & B -> _Y-
126+ ~A & ~B -> _Y+
127+ _Y => Y-
128+ }
129+ }
130+ export defcell UACELEM2 (bool? A, B; bool! Y) {
131+ prs {
132+ A & B -> Y-
133+ ~A -> Y+
134+ }
135+ }
136+ export defcell DACELEM2 (bool? A, B; bool! Y) {
137+ prs {
138+ ~A & ~B -> Y+
139+ A -> Y-
140+ }
141+ }
142+
143+ export defproc reuse_2 (bool? in; bool! out; bool! dl_in; bool? dl_out) {
144+ bool x, _x, do;
145+
146+ std::gates::ctree<2,true> C0;
147+ UACELEM2 UAC0;
148+ DACELEM2 DAC0;
149+ std::cells::INVX1 INV0;
150+ std::cells::INVX1 INV1;
151+ std::cells::NOR2X1 NOR0;
152+
153+ C0.in[0] = in;
154+ C0.in[1] = dl_out;
155+ C0.out = x;
156+
157+ UAC0.A = NOR0.Y;
158+ UAC0.B = in;
159+ UAC0.Y = do;
160+
161+ DAC0.A = x;
162+ DAC0.B = dl_out;
163+ DAC0.Y = out;
164+
165+ INV1.A = x;
166+ INV1.Y = _x;
167+ NOR0.A = _x;
168+ NOR0.B = Reset;
169+ INV0.A = do;
170+ INV0.Y = dl_in;
171+ spec {
172+ timing in+ : out+ < in-
173+ timing in- : out- < in+
174+ }
175+ }
176+ // Asymmetric Delay Elements ----------------------
177+ }
178+
179+ export namespace delay_lines {
180+
181+ // Symmetric Delay Lines -----------------------
182+ export template <pint N>
183+ defproc chain_delay_buffer (bool? in; bool! out) {
184+ std::delay_elements::delay_buffer d[N];
185+ in = d[0].in;
186+ ( i : N-1 : d[i].out = d[i+1].in; )
187+ d[N-1].out = out;
188+ spec {
189+ timing in+ : out+ < in-
190+ timing in- : out- < in+
191+ }
192+ }
193+
194+ export template <pint N, L>
195+ defproc chain_weak_delay_buffer (bool? in; bool! out) {
196+ std::delay_elements::weak_delay_buffer<L> d[N];
197+ in = d[0].in;
198+ ( i : N-1 : d[i].out = d[i+1].in; )
199+ d[N-1].out = out;
200+ spec {
201+ timing in+ : out+ < in-
202+ timing in- : out- < in+
203+ }
204+ }
205+ // Symmetric Delay Lines -----------------------
206+
207+ // Asymmetric Delay Lines ----------------------
208+ export template <pint N, REC, L>
209+ defproc chain_recursive_fast0_slow1 (bool? in; bool! out) {
210+ std::delay_elements::fast0_slow1_rec<REC, L> d[N];
211+ in = d[0].in;
212+ ( i : N-1 : d[i].out = d[i+1].in; )
213+ d[N-1].out = out;
214+ spec {
215+ timing in+ : out+ < in-
216+ timing in- : out- < in+
217+ }
218+ }
219+
220+ export template <pint N, REC, L>
221+ defproc chain_recursive_fast1_slow0 (bool? in; bool! out) {
222+ std::delay_elements::fast1_slow0_rec<REC, L> d[N];
223+ in = d[0].in;
224+ ( i : N-1 : d[i].out = d[i+1].in; )
225+ d[N-1].out = out;
226+ spec {
227+ timing in+ : out+ < in-
228+ timing in- : out- < in+
229+ }
230+ }
231+
232+ export template <pint N, L>
233+ defproc chain_reuse_1_delay_buffer (bool? in; bool! out) {
234+ std::delay_elements::reuse_1 r(in, out);
235+ chain_delay_buffer<N> d(r.dl_in, r.dl_out);
236+ spec {
237+ timing in+ : out+ < in-
238+ timing in- : out- < in+
239+ }
240+ }
241+
242+ export template <pint N, L>
243+ defproc chain_reuse_2_delay_buffer (bool? in; bool! out) {
244+ std::delay_elements::reuse_2 r(in, out);
245+ chain_delay_buffer<N> d(r.dl_in, r.dl_out);
246+ spec {
247+ timing in+ : out+ < in-
248+ timing in- : out- < in+
249+ }
250+ }
251+
252+ export template <pint N, L>
253+ defproc chain_reuse_1_weak_delay_buffer (bool? in; bool! out) {
254+ std::delay_elements::reuse_1 r(in, out);
255+ chain_weak_delay_buffer<N,L> d(r.dl_in, r.dl_out);
256+ spec {
257+ timing in+ : out+ < in-
258+ timing in- : out- < in+
259+ }
260+ }
261+
262+ export template <pint N, L>
263+ defproc chain_reuse_2_weak_delay_buffer (bool? in; bool! out) {
264+ std::delay_elements::reuse_2 r(in, out);
265+ chain_weak_delay_buffer<N,L> d(r.dl_in, r.dl_out);
266+ spec {
267+ timing in+ : out+ < in-
268+ timing in- : out- < in+
269+ }
270+ }
271+ // Asymmetric Delay Lines ----------------------
272+
273+ }
274+
275+ }
0 commit comments