Skip to content

Commit 99ba6af

Browse files
authored
Merge pull request #15 from karthisrinivasan/main
add delay line library
2 parents 5379a77 + f150f63 commit 99ba6af

File tree

4 files changed

+324
-2
lines changed

4 files changed

+324
-2
lines changed

std/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# limitations under the License.
1616
#
1717
#-------------------------------------------------------------------------
18-
TARGETACT=_all_.act channel.act data.act func.act cells.act arb.act mem.act
18+
TARGETACT=_all_.act channel.act data.act func.act cells.act arb.act mem.act delay_lines.act
1919
SUBDIRS=io gates
2020
TARGETACTSUBDIR=std
2121

std/_all_.act

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ import std::data;
3434
import std::channel;
3535
import "std/arb.act";
3636
import "std/mem.act";
37+
import "std/delay_lines.act";

std/delay_lines.act

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
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+
31+
/*
32+
Simple delay buffer consisting of two inverters
33+
*/
34+
export defproc delay_buffer (bool? in; bool! out)
35+
{
36+
std::cells::INVX1 invs[2];
37+
invs[0].A = in;
38+
invs[0].Y = invs[1].A;
39+
invs[1].Y = out;
40+
spec {
41+
timing in+ : out+ < in-
42+
timing in- : out- < in+
43+
}
44+
}
45+
46+
/*
47+
Delay buffer consisting of two weak-inverters in series.
48+
L : Length of weak transistors
49+
*/
50+
export template <pint L>
51+
defproc weak_delay_buffer (bool? in; bool! out) {
52+
bool x;
53+
prs {
54+
in<1,L> => x-
55+
x<1,L> => out-
56+
}
57+
spec {
58+
timing in+ : out+ < in-
59+
timing in- : out- < in+
60+
}
61+
}
62+
// Symmetric Delay Elements -----------------------
63+
64+
// Asymmetric Delay Elements ----------------------
65+
// Asymmetric : Different propagation delays for rising edge (1) and falling edge (0)
66+
/*
67+
Recursive asymmetric delay lines that use themselves to create long delays.
68+
REC: Recursion level
69+
L : Length of weak transistors
70+
Base case: two asymmetric inverters in series
71+
Recursive step: insert REC-1 of the correct type on the slow path to make it even slower
72+
Has additional transistor to prevent transient short and reduce power consumption
73+
*/
74+
/*
75+
Fast-0, Slow-1
76+
Delay of rising edge - high
77+
Delay of falling edge - 2 transitions
78+
*/
79+
export template <pint REC, L> defproc fast0_slow1_rec (bool? in; bool! out);
80+
81+
/*
82+
Fast-1, Slow-0
83+
Delay of falling edge - high
84+
Delay of rising edge - 2 transitions
85+
*/
86+
export template <pint REC, L> defproc fast1_slow0_rec (bool? in; bool! out);
87+
88+
export template <pint REC, L>
89+
defproc fast0_slow1_rec (bool? in; bool! out) {
90+
{ REC>=0 : "what" };
91+
bool x; bool f0s1out, f1s0out;
92+
[ REC=0 -> f0s1out = in;
93+
f1s0out = x;
94+
[]REC>0 -> fast0_slow1_rec<REC-1,L> f0s1r(in); f0s1out = f0s1r.out;
95+
fast1_slow0_rec<REC-1,L> f1s0r(x); f1s0out = f1s0r.out;
96+
]
97+
prs {
98+
[keeper=0] f0s1out<1,L> & in<1,1> -> x-
99+
[keeper=0] ~in<1,1> -> x+
100+
[keeper=0] x<1,1> -> out-
101+
[keeper=0] ~f1s0out<1,L> & ~x<1,1> -> out+
102+
}
103+
spec {
104+
timing in+ : out+ < in-
105+
timing in- : out- < in+
106+
}
107+
}
108+
109+
export template <pint REC, L>
110+
defproc fast1_slow0_rec (bool? in; bool! out) {
111+
{ REC>=0 : "what" };
112+
bool x; bool f0s1out, f1s0out;
113+
[ REC=0 -> f1s0out = in;
114+
f0s1out = x;
115+
[]REC>0 -> fast1_slow0_rec<REC-1,L> f1s0r(in); f1s0out = f1s0r.out;
116+
fast0_slow1_rec<REC-1,L> f0s1r(x); f0s1out = f0s1r.out;
117+
]
118+
prs {
119+
[keeper=0] in<1,1> -> x-
120+
[keeper=0] ~f1s0out<1,L> & ~in<1,1> -> x+
121+
[keeper=0] f0s1out<1,L> & x<1,1> -> out-
122+
[keeper=0] ~x<1,1> -> out+
123+
}
124+
spec {
125+
timing in+ : out+ < in-
126+
timing in- : out- < in+
127+
}
128+
}
129+
130+
/*
131+
Meta-elements that use a symmetric delay line twice (0-delay + 1-delay)
132+
to simulate an asymmetric delay line.
133+
The symmetric delay line component must be connected between dl_in and dl_out.
134+
Slow rising edge (1) and fast falling edge (0).
135+
*/
136+
/*
137+
Delay of rising edge - (0-delay + 1-delay) of symm. DL + 5 transitions
138+
Delay of falling edge - 2 transitions
139+
*/
140+
export defproc reuse_1 (bool? in; bool! out; bool! dl_in; bool? dl_out) {
141+
bool x, y, _y;
142+
y = dl_in;
143+
std::cells::NOR2X1 nor;
144+
nor.A = dl_out;
145+
nor.B = x;
146+
nor.Y = out;
147+
prs {
148+
_y => y-
149+
Reset | in & x -> _y-
150+
~Reset & ~x -> _y+
151+
dl_out & in #> x-
152+
}
153+
spec {
154+
timing in+ : out+ < in-
155+
timing in- : out- < in+
156+
}
157+
}
158+
159+
export defcell PCELEM2 (bool? A, B; bool! Y) {
160+
bool _Y;
161+
prs {
162+
A & B -> _Y-
163+
~A & ~B -> _Y+
164+
_Y => Y-
165+
}
166+
}
167+
export defcell UACELEM2 (bool? A, B; bool! Y) {
168+
prs {
169+
A & B -> Y-
170+
~A -> Y+
171+
}
172+
}
173+
export defcell DACELEM2 (bool? A, B; bool! Y) {
174+
prs {
175+
~A & ~B -> Y+
176+
A -> Y-
177+
}
178+
}
179+
180+
/*
181+
Delay of rising edge - (0-delay + 1-delay) of symm. DL + 7 transitions
182+
Delay of falling edge - 2 transitions
183+
*/
184+
export defproc reuse_2 (bool? in; bool! out; bool! dl_in; bool? dl_out) {
185+
bool x, _x, do;
186+
187+
std::gates::ctree<2,true> C0;
188+
UACELEM2 UAC0;
189+
DACELEM2 DAC0;
190+
std::cells::INVX1 INV0;
191+
std::cells::INVX1 INV1;
192+
std::cells::NOR2X1 NOR0;
193+
194+
C0.in[0] = in;
195+
C0.in[1] = dl_out;
196+
C0.out = x;
197+
198+
UAC0.A = NOR0.Y;
199+
UAC0.B = in;
200+
UAC0.Y = do;
201+
202+
DAC0.A = x;
203+
DAC0.B = dl_out;
204+
DAC0.Y = out;
205+
206+
INV1.A = x;
207+
INV1.Y = _x;
208+
NOR0.A = _x;
209+
NOR0.B = Reset;
210+
INV0.A = do;
211+
INV0.Y = dl_in;
212+
spec {
213+
timing in+ : out+ < in-
214+
timing in- : out- < in+
215+
}
216+
}
217+
// Asymmetric Delay Elements ----------------------
218+
}
219+
220+
export namespace delay_lines {
221+
/*
222+
Chains of delay elements.
223+
N : number of elements in series.
224+
For other parameters specific to each, see the delay elements above.
225+
*/
226+
227+
// Symmetric Delay Lines -----------------------
228+
export template <pint N>
229+
defproc chain_delay_buffer (bool? in; bool! out) {
230+
std::delay_elements::delay_buffer d[N];
231+
in = d[0].in;
232+
( i : N-1 : d[i].out = d[i+1].in; )
233+
d[N-1].out = out;
234+
spec {
235+
timing in+ : out+ < in-
236+
timing in- : out- < in+
237+
}
238+
}
239+
240+
export template <pint N, L>
241+
defproc chain_weak_delay_buffer (bool? in; bool! out) {
242+
std::delay_elements::weak_delay_buffer<L> d[N];
243+
in = d[0].in;
244+
( i : N-1 : d[i].out = d[i+1].in; )
245+
d[N-1].out = out;
246+
spec {
247+
timing in+ : out+ < in-
248+
timing in- : out- < in+
249+
}
250+
}
251+
// Symmetric Delay Lines -----------------------
252+
253+
// Asymmetric Delay Lines ----------------------
254+
export template <pint N, REC, L>
255+
defproc chain_recursive_fast0_slow1 (bool? in; bool! out) {
256+
std::delay_elements::fast0_slow1_rec<REC, L> d[N];
257+
in = d[0].in;
258+
( i : N-1 : d[i].out = d[i+1].in; )
259+
d[N-1].out = out;
260+
spec {
261+
timing in+ : out+ < in-
262+
timing in- : out- < in+
263+
}
264+
}
265+
266+
export template <pint N, REC, L>
267+
defproc chain_recursive_fast1_slow0 (bool? in; bool! out) {
268+
std::delay_elements::fast1_slow0_rec<REC, L> d[N];
269+
in = d[0].in;
270+
( i : N-1 : d[i].out = d[i+1].in; )
271+
d[N-1].out = out;
272+
spec {
273+
timing in+ : out+ < in-
274+
timing in- : out- < in+
275+
}
276+
}
277+
278+
export template <pint N, L>
279+
defproc chain_reuse_1_delay_buffer (bool? in; bool! out) {
280+
std::delay_elements::reuse_1 r(in, out);
281+
chain_delay_buffer<N> d(r.dl_in, r.dl_out);
282+
spec {
283+
timing in+ : out+ < in-
284+
timing in- : out- < in+
285+
}
286+
}
287+
288+
export template <pint N, L>
289+
defproc chain_reuse_2_delay_buffer (bool? in; bool! out) {
290+
std::delay_elements::reuse_2 r(in, out);
291+
chain_delay_buffer<N> d(r.dl_in, r.dl_out);
292+
spec {
293+
timing in+ : out+ < in-
294+
timing in- : out- < in+
295+
}
296+
}
297+
298+
export template <pint N, L>
299+
defproc chain_reuse_1_weak_delay_buffer (bool? in; bool! out) {
300+
std::delay_elements::reuse_1 r(in, out);
301+
chain_weak_delay_buffer<N,L> d(r.dl_in, r.dl_out);
302+
spec {
303+
timing in+ : out+ < in-
304+
timing in- : out- < in+
305+
}
306+
}
307+
308+
export template <pint N, L>
309+
defproc chain_reuse_2_weak_delay_buffer (bool? in; bool! out) {
310+
std::delay_elements::reuse_2 r(in, out);
311+
chain_weak_delay_buffer<N,L> d(r.dl_in, r.dl_out);
312+
spec {
313+
timing in+ : out+ < in-
314+
timing in- : out- < in+
315+
}
316+
}
317+
// Asymmetric Delay Lines ----------------------
318+
319+
}
320+
321+
}

std/gates/treegates.act

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ defproc sigbuf_gen (bool in; bool out[N])
330330
export defproc sigbuf <: sigbuf_gen<0> () { }
331331
export defproc sigbufa <: sigbuf_gen<1> () { }
332332

333-
defcell xor2 (bool? in[2]; bool! out)
333+
export defcell xor2 (bool? in[2]; bool! out)
334334
{
335335
bool _in0, _in1;
336336
prs {

0 commit comments

Comments
 (0)