Skip to content

Commit d46b290

Browse files
committed
[LTL] Update delay syntax to include clock and edge specifications
1 parent 55a94d5 commit d46b290

File tree

2 files changed

+58
-39
lines changed

2 files changed

+58
-39
lines changed

docs/Dialects/LTL.md

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,54 +48,54 @@ a ##1 b ##1 c // 1 cycle delay between a, b, and c
4848

4949
In the simplest form, a cycle delay can appear as a prefix of another sequence, e.g., `##1 a`. This is essentially a concatenation with only one sequence, `a`, and an initial cycle delay of the concatenation of `1`. The prefix delays map to the LTL dialect as follows:
5050

51-
- `##N seq`. **Fixed delay.** Sequence `seq` has to match exactly `N` cycles in the future. Equivalent to `ltl.delay %seq, N, 0`.
52-
- `##[N:M] seq`. **Bounded range delay.** Sequence `seq` has to match anywhere between `N` and `M` cycles in the future, inclusive. Equivalent to `ltl.delay %seq, N, (M-N)`
53-
- `##[N:$] seq`. **Unbounded range delay.** Sequence `seq` has to match anywhere at or beyond `N` cycles in the future, after a finite amount of cycles. Equivalent to `ltl.delay %seq, N`.
54-
- `##[*] seq`. Shorthand for `##[0:$]`. Equivalent to `ltl.delay %seq, 0`.
55-
- `##[+] seq`. Shorthand for `##[1:$]`. Equivalent to `ltl.delay %seq, 1`.
51+
- `##N seq`. **Fixed delay.** Sequence `seq` has to match exactly `N` cycles in the future. Equivalent to `ltl.delay %clk, posedge, %seq, N, 0`.
52+
- `##[N:M] seq`. **Bounded range delay.** Sequence `seq` has to match anywhere between `N` and `M` cycles in the future, inclusive. Equivalent to `ltl.delay %clk, posedge, %seq, N, (M-N)`
53+
- `##[N:$] seq`. **Unbounded range delay.** Sequence `seq` has to match anywhere at or beyond `N` cycles in the future, after a finite amount of cycles. Equivalent to `ltl.delay %clk, posedge, %seq, N`.
54+
- `##[*] seq`. Shorthand for `##[0:$]`. Equivalent to `ltl.delay %clk, posedge, %seq, 0`.
55+
- `##[+] seq`. Shorthand for `##[1:$]`. Equivalent to `ltl.delay %clk, posedge, %seq, 1`.
5656

5757
Concatenation of two sequences always involves a cycle delay specification in between them, e.g., `a ##1 b` where sequence `b` starts in the cycle after `a` ends. Zero-cycle delays can be specified, e.g., `a ##0 b` where `b` starts in the same cycle as `a` ends. If `a` and `b` are booleans, `a ##0 b` is equivalent to `a && b`.
5858

5959
The dialect separates concatenation and cycle delay into two orthogonal operations, `ltl.concat` and `ltl.delay`, respectively. The former models concatenation as `a ##0 b`, and the latter models delay as a prefix `##1 c`. The SVA concatenations with their infix delays map to the LTL dialect as follows:
6060

6161
- `seqA ##N seqB`. **Binary concatenation.** Sequence `seqB` follows `N` cycles after `seqA`. This can be represented as `seqA ##0 (##N seqB)`, which is equivalent to
6262
```
63-
%0 = ltl.delay %seqB, N, 0
63+
%0 = ltl.delay %clk, posedge, %seqB, N, 0
6464
ltl.concat %seqA, %0
6565
```
6666

6767
- `seqA ##N seqB ##M seqC`. **Variadic concatenation.** Sequence `seqC` follows `M` cycles after `seqB`, which itself follows `N` cycles after `seqA`. This can be represented as `seqA ##0 (##N seqB) ##0 (##M seqC)`, which is equivalent to
6868
```
69-
%0 = ltl.delay %seqB, N, 0
70-
%1 = ltl.delay %seqC, M, 0
69+
%0 = ltl.delay %clk, posedge, %seqB, N, 0
70+
%1 = ltl.delay %clk, posedge, %seqC, M, 0
7171
ltl.concat %seqA, %0, %1
7272
```
7373
Since concatenation is associative, this is also equivalent to `seqA ##N (seqB ##M seqC)`:
7474
```
75-
%0 = ltl.delay %seqC, M, 0
75+
%0 = ltl.delay %clk, posedge, %seqC, M, 0
7676
%1 = ltl.concat %seqB, %0
77-
%2 = ltl.delay %1, N, 0
77+
%2 = ltl.delay %clk, posedge, %1, N, 0
7878
ltl.concat %seqA, %2
7979
```
8080
And also `(seqA ##N seqB) ##M seqC`:
8181
```
82-
%0 = ltl.delay %seqB, N, 0
82+
%0 = ltl.delay %clk, posedge, %seqB, N, 0
8383
%1 = ltl.concat %seqA, %0
84-
%2 = ltl.delay %seqC, M, 0
84+
%2 = ltl.delay %clk, posedge, %seqC, M, 0
8585
ltl.concat %1, %2
8686
```
8787

8888
- `##N seqA ##M seqB`. **Initial delay.** Sequence `seqB` follows `M` cycles afer `seqA`, which itself starts `N` cycles in the future. This is equivalent to a delay on `seqA` within the concatenation:
8989
```
90-
%0 = ltl.delay %seqA, N, 0
91-
%1 = ltl.delay %seqB, M, 0
90+
%0 = ltl.delay %clk, posedge, %seqA, N, 0
91+
%1 = ltl.delay %clk, posedge, %seqB, M, 0
9292
ltl.concat %0, %1
9393
```
9494
Alternatively, the delay can also be placed on the entire concatenation:
9595
```
96-
%0 = ltl.delay %seqB, M, 0
96+
%0 = ltl.delay %clk, posedge, %seqB, M, 0
9797
%1 = ltl.concat %seqA, %0
98-
ltl.delay %1, N, 0
98+
ltl.delay %clk, posedge, %1, N, 0
9999
```
100100

101101
- Only the fixed delay `##N` is shown here for simplicity, but the examples extend to the other delay flavors `##[N:M]`, `##[N:$]`, `##[*]`, and `##[+]`.
@@ -160,6 +160,25 @@ Sequence and property expressions in SVAs can specify a clock with respect to wh
160160
- `@(negedge clk) seqOrProp`. **Trigger on high-to-low clock edge.** Equivalent to `ltl.clock %seqOrProp, negedge %clk`.
161161
- `@(edge clk) seqOrProp`. **Trigger on any clock edge.** Equivalent to `ltl.clock %seqOrProp, edge %clk`.
162162

163+
#### Delay clocking (concise)
164+
165+
`ltl.delay` takes a clock `Value` and a `ClockEdgeAttr` as its first two
166+
operands:
167+
168+
```
169+
ltl.delay %clock, <edge>, %input, <delay>[, <length>]
170+
```
171+
172+
`%clock` is an `i1` value (e.g. a module clock); `<edge>` is `posedge`,
173+
`negedge`, or `edge`. The `delay`/`length` are counted on the specified
174+
clock/edge (for example `ltl.delay %clk, posedge, %s, 3` means `%s` must hold
175+
3 cycles later on `%clk` rising edges). `ltl.clock` globally associates a
176+
sequence/property with a clock/edge; using the same pair in `ltl.delay`
177+
keeps expressions in the same clocking domain.
178+
179+
Note: lowering may insert an explicit clock value (e.g. `hw.constant` or
180+
`seq.from_clock`) when a direct `Value` for the clock is not available.
181+
163182

164183
### Disable Iff
165184

@@ -220,13 +239,13 @@ Knowing how to map SVA constructs to CIRCT is important to allow these to expres
220239

221240
- **`a ##n b`**:
222241
```mlir
223-
%a_n = ltl.delay %a, n, 0 : i1
242+
%a_n = ltl.delay %clk, posedge, %a, n, 0 : i1
224243
%anb = ltl.concat %a_n, %b : !ltl.sequence
225244
```
226245

227246
- **`a ##[n:m] b`**:
228247
```mlir
229-
%a_n = ltl.delay %a, n, (m-n) : i1
248+
%a_n = ltl.delay %clk, posedge, %a, n, (m-n) : i1
230249
%anb = ltl.concat %a_n, %b : !ltl.sequence
231250
```
232251

@@ -257,15 +276,15 @@ Knowing how to map SVA constructs to CIRCT is important to allow these to expres
257276

258277
- **`s1 ##[+] s2`**:
259278
```mlir
260-
%ds1 = ltl.delay %s1, 1
279+
%ds1 = ltl.delay %clk, posedge, %s1, 1
261280
%s1s2 = ltl.concat %ds1, %s2 : !ltl.sequence
262-
```
281+
```
263282

264283
- **`s1 ##[*] s2`**:
265284
```mlir
266-
%ds1 = ltl.delay %s1, 0
285+
%ds1 = ltl.delay %clk, posedge, %s1, 0
267286
%s1s2 = ltl.concat %ds1, %s2 : !ltl.sequence
268-
```
287+
```
269288

270289
- **`s1 and s2`**:
271290
```mlir
@@ -299,8 +318,8 @@ ltl.not %s1 : !ltl.sequence
299318
```mlir
300319
%c1 = hw.constant 1 : i1
301320
%rep1 = ltl.repeat %c1, 0 : !ltl.sequence
302-
%drep1 = ltl.delay %rep1, 1, 0 : !ltl.sequence
303-
%ds1 = ltl.delay %s1, 1, 0 : !ltl.sequence
321+
%drep1 = ltl.delay %clk, posedge, %rep1, 1, 0 : !ltl.sequence
322+
%ds1 = ltl.delay %clk, posedge, %s1, 1, 0 : !ltl.sequence
304323
%evs1 = ltl.concat %drep1, %ds1, %c1 : !ltl.sequence
305324
%res = ltl.intersect %evs1, %s2 : !ltl.sequence
306325
```
@@ -313,7 +332,7 @@ ltl.not %s1 : !ltl.sequence
313332
- **`s |=> p`**:
314333
```mlir
315334
%c1 = hw.constant 1 : i1
316-
%ds = ltl.delay %s, 1, 0 : i1
335+
%ds = ltl.delay %clk, posedge, %s, 1, 0 : i1
317336
%antecedent = ltl.concat %ds, %c1 : !ltl.sequence
318337
%impl = ltl.implication %antecedent, %p : !ltl.property
319338
```
@@ -342,7 +361,7 @@ ltl.not %s1 : !ltl.sequence
342361
- **`s #=# p`**:
343362
```mlir
344363
%np = ltl.not %p : !ltl.property
345-
%ds = ltl.delay %s, 1, 0 : !ltl.sequence
364+
%ds = ltl.delay %clk, posedge, %s, 1, 0 : !ltl.sequence
346365
%c1 = hw.constant 1 : i1
347366
%ant = ltl.concat %ds, c1 : !ltl.sequence
348367
%impl = ltl.implication %ant, %np : !ltl.property
@@ -354,13 +373,13 @@ ltl.not %s1 : !ltl.sequence
354373

355374
- **`nexttime p`**:
356375
```mlir
357-
ltl.delay %p, 1, 0 : !ltl.sequence
358-
```
376+
ltl.delay %clk, posedge, %p, 1, 0 : !ltl.sequence
377+
```
359378

360379
- **`nexttime[n] p`**:
361380
```mlir
362-
ltl.delay %p, n, 0 : !ltl.sequence
363-
```
381+
ltl.delay %clk, posedge, %p, n, 0 : !ltl.sequence
382+
```
364383

365384
- **`s_nexttime p`**: not really distinguishable from the weak version in CIRCT.
366385
- **`s_nexttime[n] p`**: not really distinguishable from the weak version in CIRCT.
@@ -418,13 +437,13 @@ The `ltl.delay` sequence operation represents various shorthands for the *next*/
418437

419438
| Operation | LTL Formula |
420439
|----------------------|-----------------------------|
421-
| `ltl.delay %a, 0, 0` | a |
422-
| `ltl.delay %a, 1, 0` | **X**a |
423-
| `ltl.delay %a, 3, 0` | **XXX**a |
424-
| `ltl.delay %a, 0, 2` | a ∨ **X**a ∨ **XX**a |
425-
| `ltl.delay %a, 1, 2` | **X**(a ∨ **X**a ∨ **XX**a) |
426-
| `ltl.delay %a, 0` | **F**a |
427-
| `ltl.delay %a, 2` | **XXF**a |
440+
| `ltl.delay %clk, posedge, %a, 0, 0` | a |
441+
| `ltl.delay %clk, posedge, %a, 1, 0` | **X**a |
442+
| `ltl.delay %clk, posedge, %a, 3, 0` | **XXX**a |
443+
| `ltl.delay %clk, posedge, %a, 0, 2` | a ∨ **X**a ∨ **XX**a |
444+
| `ltl.delay %clk, posedge, %a, 1, 2` | **X**(a ∨ **X**a ∨ **XX**a) |
445+
| `ltl.delay %clk, posedge, %a, 0` | **F**a |
446+
| `ltl.delay %clk, posedge, %a, 2` | **XXF**a |
428447

429448

430449
### Until and Eventually

docs/FormalVerification.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ hw.module @mod(in %clk: !seq.clock, in %arg0: i32, in %rst: i1,
232232
%3 = comb.icmp eq, %2, %c0_i32 : i32
233233
verif.assume %3 : i1
234234
%4 = comb.xor %rst, %true : i1
235-
%5 = ltl.delay %4, 2 : i1
235+
%5 = ltl.delay %clk, posedge, %4, 2 : i1
236236
%6 = ltl.concat %rst, %5 : i1, !ltl.sequence
237237
%7 = ltl.clock %6, posedge %clk : !ltl.sequence
238238
verif.assume %7 : !ltl.sequence
@@ -265,7 +265,7 @@ verif.bmc bound 10 {
265265
%3 = comb.icmp eq, %2, %c0_i32 : i32
266266
verif.assume %3 : i1
267267
%4 = comb.xor %rst, %true : i1
268-
%5 = ltl.delay %4, 2 : i1
268+
%5 = ltl.delay %clk, posedge, %4, 2 : i1
269269
%6 = ltl.concat %rst, %5 : i1, !ltl.sequence
270270
%7 = ltl.clock %6, posedge %clk : !ltl.sequence
271271
verif.assume %7 : !ltl.sequence

0 commit comments

Comments
 (0)