Skip to content

Commit 9351303

Browse files
authored
[Seq] FIFO: permit any type and add read latency (#7810)
- Makes $input and $output allow any type rather than just a bit vector. - Adds read latency attribute to specify the number of cycles after which rdEn is asserted that data appears in the output.
1 parent e666347 commit 9351303

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

include/circt/Dialect/Seq/SeqOps.td

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@ def FIFOOp : SeqOp<"fifo", [
277277
operations.
278278
The fifo operation is configurable with the following parameters:
279279
1. Depth (cycles)
280-
2. Almost full/empty thresholds (optional). If not provided, these will
280+
2. Read latency (cycles) is the number of cycles it takes for a read to
281+
return data after the read enable signal is asserted.
282+
3. Almost full/empty thresholds (optional). If not provided, these will
281283
be asserted when the FIFO is full/empty.
282284

283285
Like `seq.hlmem` there are no guarantees that all possible fifo configuration
@@ -286,18 +288,21 @@ def FIFOOp : SeqOp<"fifo", [
286288
}];
287289

288290
let arguments = (ins
289-
HWIntegerType:$input, I1:$rdEn, I1:$wrEn, ClockType:$clk, I1:$rst,
291+
AnyType:$input, I1:$rdEn, I1:$wrEn, ClockType:$clk, I1:$rst,
290292
ConfinedAttr<I64Attr, [IntMinValue<1>]>:$depth,
293+
DefaultValuedOptionalAttr<ConfinedAttr<I64Attr, [IntMinValue<0>]>, "0">
294+
:$rdLatency,
291295
OptionalAttr<ConfinedAttr<I64Attr, [IntMinValue<0>]>>:$almostFullThreshold,
292296
OptionalAttr<ConfinedAttr<I64Attr, [IntMinValue<0>]>>:$almostEmptyThreshold
293297
);
294298

295299
let results = (outs
296-
HWIntegerType:$output, I1:$full, I1:$empty, Optional<I1>:$almostFull,
300+
AnyType:$output, I1:$full, I1:$empty, Optional<I1>:$almostFull,
297301
Optional<I1>:$almostEmpty);
298302

299303
let assemblyFormat = [{
300304
`depth` $depth
305+
(`rd_latency` $rdLatency^)?
301306
custom<FIFOAFThreshold>($almostFullThreshold, type($almostFull))
302307
custom<FIFOAEThreshold>($almostEmptyThreshold, type($almostEmpty))
303308
`in` $input `rdEn` $rdEn `wrEn` $wrEn `clk` $clk `rst` $rst attr-dict `:` type($input)

lib/Dialect/Seq/Transforms/LowerSeqFIFO.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ struct FIFOLowering : public OpConversionPattern<seq::FIFOOp> {
6969

7070
Value readData = rewriter.create<seq::ReadPortOp>(
7171
loc, hlmem, llvm::SmallVector<Value>{rdAddr}, adaptor.getRdEn(),
72-
/*latency*/ 0);
72+
mem.getRdLatency());
7373
rewriter.create<seq::WritePortOp>(loc, hlmem,
7474
llvm::SmallVector<Value>{wrAddr},
7575
adaptor.getInput(), adaptor.getWrEn(),

test/Dialect/Seq/lower-fifo.mlir

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ hw.module @fifo1(in %clk : !seq.clock, in %rst : i1, in %in : i32, in %rdEn : i1
4747
}
4848

4949

50-
// CHECK: hw.module @fifo2(in %[[CLOCK:.*]] : !seq.clock, in %[[VAL_1:.*]] : i1, in %[[VAL_2:.*]] : i32, in %[[VAL_3:.*]] : i1, in %[[VAL_4:.*]] : i1, out out : i32, out empty : i1, out full : i1, out almost_empty : i1, out almost_full : i1) {
50+
// CHECK: hw.module @fifo2(in %[[CLOCK:.*]] : !seq.clock, in %[[VAL_1:.*]] : i1, in %[[VAL_2:.*]] : [[TY:.+]], in %[[VAL_3:.*]] : i1, in %[[VAL_4:.*]] : i1, out out : [[TY]], out empty : i1, out full : i1, out almost_empty : i1, out almost_full : i1) {
5151
// CHECK: %[[VAL_5:.*]] = hw.constant 2 : i3
5252
// CHECK: %[[VAL_8:.*]] = hw.constant -1 : i3
5353
// CHECK: %[[VAL_7:.*]] = hw.constant true
@@ -57,11 +57,11 @@ hw.module @fifo1(in %clk : !seq.clock, in %rst : i1, in %in : i32, in %rdEn : i1
5757
// CHECK: %[[VAL_11:.*]] = hw.constant 0 : i3
5858
// CHECK: %[[VAL_12:.*]] = hw.constant 1 : i2
5959
// CHECK: %[[VAL_13:.*]] = seq.compreg sym @fifo_count %[[VAL_14:.*]], %[[CLOCK]] reset %[[VAL_1]], %[[VAL_11]] : i3
60-
// CHECK: %[[VAL_15:.*]] = seq.hlmem @fifo_mem %[[CLOCK]], %[[VAL_1]] : <4xi32>
60+
// CHECK: %[[VAL_15:.*]] = seq.hlmem @fifo_mem %[[CLOCK]], %[[VAL_1]] : <4x[[TY]]>
6161
// CHECK: %[[VAL_16:.*]] = seq.compreg sym @fifo_rd_addr %[[VAL_17:.*]], %[[CLOCK]] reset %[[VAL_1]], %[[VAL_6]] : i2
6262
// CHECK: %[[VAL_18:.*]] = seq.compreg sym @fifo_wr_addr %[[VAL_19:.*]], %[[CLOCK]] reset %[[VAL_1]], %[[VAL_6]] : i2
63-
// CHECK: %[[VAL_20:.*]] = seq.read %[[VAL_15]]{{\[}}%[[VAL_16]]] rden %[[VAL_3]] {latency = 0 : i64} : !seq.hlmem<4xi32>
64-
// CHECK: seq.write %[[VAL_15]]{{\[}}%[[VAL_18]]] %[[VAL_2]] wren %[[VAL_4]] {latency = 1 : i64} : !seq.hlmem<4xi32>
63+
// CHECK: %[[VAL_20:.*]] = seq.read %[[VAL_15]]{{\[}}%[[VAL_16]]] rden %[[VAL_3]] {latency = 1 : i64} : !seq.hlmem<4x[[TY]]>
64+
// CHECK: seq.write %[[VAL_15]]{{\[}}%[[VAL_18]]] %[[VAL_2]] wren %[[VAL_4]] {latency = 1 : i64} : !seq.hlmem<4x[[TY]]>
6565
// CHECK: %[[VAL_21:.*]] = comb.icmp eq %[[VAL_13]], %[[VAL_9]] {sv.namehint = "fifo_full"} : i3
6666
// CHECK: %[[VAL_22:.*]] = comb.icmp eq %[[VAL_13]], %[[VAL_11]] {sv.namehint = "fifo_empty"} : i3
6767
// CHECK: %[[VAL_23:.*]] = comb.xor %[[VAL_3]], %[[VAL_7]] : i1
@@ -90,9 +90,10 @@ hw.module @fifo1(in %clk : !seq.clock, in %rst : i1, in %in : i32, in %rdEn : i1
9090
// CHECK: %[[VAL_43:.*]] = comb.extract %[[VAL_13]] from 1 : (i3) -> i2
9191
// CHECK: %[[VAL_44:.*]] = comb.icmp ne %[[VAL_43]], %[[VAL_6]] {sv.namehint = "fifo_almost_full"} : i2
9292
// CHECK: %[[VAL_45:.*]] = comb.icmp ult %[[VAL_13]], %[[VAL_5]] {sv.namehint = "fifo_almost_empty"} : i3
93-
// CHECK: hw.output %[[VAL_20]], %[[VAL_22]], %[[VAL_21]], %[[VAL_45]], %[[VAL_44]] : i32, i1, i1, i1, i1
93+
// CHECK: hw.output %[[VAL_20]], %[[VAL_22]], %[[VAL_21]], %[[VAL_45]], %[[VAL_44]] : [[TY]], i1, i1, i1, i1
9494
// CHECK: }
95-
hw.module @fifo2(in %clk : !seq.clock, in %rst : i1, in %in : i32, in %rdEn : i1, in %wrEn : i1, out out: i32, out empty: i1, out full: i1, out almost_empty : i1, out almost_full : i1) {
96-
%out, %full, %empty, %almostFull, %almostEmpty = seq.fifo depth 4 almost_full 2 almost_empty 1 in %in rdEn %rdEn wrEn %wrEn clk %clk rst %rst : i32
97-
hw.output %out, %empty, %full, %almostEmpty, %almostFull : i32, i1, i1, i1, i1
95+
!testType = !hw.array<2xi32>
96+
hw.module @fifo2(in %clk : !seq.clock, in %rst : i1, in %in : !testType, in %rdEn : i1, in %wrEn : i1, out out: !testType, out empty: i1, out full: i1, out almost_empty : i1, out almost_full : i1) {
97+
%out, %full, %empty, %almostFull, %almostEmpty = seq.fifo depth 4 rd_latency 1 almost_full 2 almost_empty 1 in %in rdEn %rdEn wrEn %wrEn clk %clk rst %rst : !testType
98+
hw.output %out, %empty, %full, %almostEmpty, %almostFull : !testType, i1, i1, i1, i1
9899
}

0 commit comments

Comments
 (0)