Skip to content

Commit

Permalink
[PyCDE] Binding for FIFOs (#7806)
Browse files Browse the repository at this point in the history
Adds a `seq` module which contains a FIFO class which produces a `seq.fifo` op. Does not include anything related to almost full/empty.
  • Loading branch information
teqdruid authored Nov 14, 2024
1 parent 9351303 commit 2cdde17
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
1 change: 1 addition & 0 deletions frontends/PyCDE/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ declare_mlir_python_sources(PyCDESources
pycde/system.py
pycde/devicedb.py
pycde/instance.py
pycde/seq.py
pycde/signals.py
pycde/ndarray.py
pycde/esi.py
Expand Down
61 changes: 61 additions & 0 deletions frontends/PyCDE/src/pycde/seq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

from .circt.dialects import seq as raw_seq
from .constructs import Wire

from .types import Bits, Type
from .signals import _FromCirctValue, BitsSignal, ClockSignal, Signal


class FIFO:
"""Creates a FIFO operation with the specified type, depth, clock, and reset
signal. Adds push and pop methods to wire up the FIFO."""

def __init__(self,
type: Type,
depth: int,
clk: ClockSignal,
rst: BitsSignal,
rd_latency: int = 0):
self.type = type
self.input = Wire(type)
self.wr_en = Wire(Bits(1))
self.rd_en = Wire(Bits(1))
i1 = Bits(1)._type
self.fifo = raw_seq.FIFOOp(self.input.type._type,
i1,
i1,
i1,
i1,
self.input.value,
self.rd_en.value,
self.wr_en.value,
clk.value,
rst.value,
depth,
rdLatency=rd_latency)
self._output = _FromCirctValue(self.fifo.output)

def push(self, data: Signal, en: BitsSignal):
"""Connect 'data' to the FIFO input and 'en' to write enable."""
self.input.assign(data)
self.wr_en.assign(en)

def pop(self, en: BitsSignal):
"""Wire up 'en' to read enable and returns the FIFO output."""
self.rd_en.assign(en)
return self._output

@property
def output(self):
return self._output

@property
def full(self):
return _FromCirctValue(self.fifo.full)

@property
def empty(self):
return _FromCirctValue(self.fifo.empty)
53 changes: 53 additions & 0 deletions frontends/PyCDE/test/test_seq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# RUN: %PYTHON% %s | FileCheck %s

from pycde import Module, Clock, Reset, Input, Output
from pycde.seq import FIFO
from pycde.testing import unittestmodule
from pycde.types import Bits, UInt

from pycde.module import generator

# CHECK-LABEL: hw.module @SimpleFIFOTest(in %clk : !seq.clock, in %rst : i1)
# CHECK-NEXT: %false = hw.constant false
# CHECK-NEXT: [[R0:%.+]] = hwarith.constant 0 : ui32
# CHECK-NEXT: %out, %full, %empty, %almostFull, %almostEmpty = seq.fifo depth 16 in [[R0]] rdEn %false wrEn %false clk %clk rst %rst : ui32


@unittestmodule(run_passes=False)
class SimpleFIFOTest(Module):
clk = Clock()
rst = Reset()

@generator
def construct(ports):
c0 = Bits(1)(0)
ui32 = UInt(32)(0)

fifo = FIFO(type=UInt(32), depth=16, clk=ports.clk, rst=ports.rst)
fifo.push(ui32, c0)
fifo.pop(c0)


# CHECK-LABEL: hw.module @SimpleFIFOTestRd1(in %clk : !seq.clock, in %rst : i1)
# CHECK-NEXT: %false = hw.constant false
# CHECK-NEXT: [[R0:%.+]] = hwarith.constant 0 : ui32
# CHECK-NEXT: %out, %full, %empty, %almostFull, %almostEmpty = seq.fifo depth 16 rd_latency 1 in [[R0]] rdEn %false wrEn %false clk %clk rst %rst : ui32


@unittestmodule(run_passes=False)
class SimpleFIFOTestRd1(Module):
clk = Clock()
rst = Reset()

@generator
def construct(ports):
c0 = Bits(1)(0)
ui32 = UInt(32)(0)

fifo = FIFO(type=UInt(32),
depth=16,
clk=ports.clk,
rst=ports.rst,
rd_latency=1)
fifo.push(ui32, c0)
fifo.pop(c0)

0 comments on commit 2cdde17

Please sign in to comment.