mirror of https://github.com/llvm/circt.git
[PyCDE] Support for ESI MMIO service -- read side only (#6590)
Add support for the MMIO ESI service to PyCDE. Most implementations of this service will embed the compressed manifest, which this PR is intended to support. So let's just expose the read service for now.
This commit is contained in:
parent
90f2bea727
commit
14b8450bc5
|
@ -4,10 +4,10 @@
|
|||
|
||||
from .common import (AppID, Input, Output, _PyProxy, PortError)
|
||||
from .module import Generator, Module, ModuleLikeBuilderBase, PortProxyBase
|
||||
from .signals import BundleSignal, ChannelSignal, Signal, _FromCirctValue
|
||||
from .signals import BundleSignal, ChannelSignal, Signal, Struct, _FromCirctValue
|
||||
from .system import System
|
||||
from .types import (Bits, Bundle, BundledChannel, Channel, ChannelDirection,
|
||||
Type, types, _FromCirctType)
|
||||
StructType, Type, types, UInt, _FromCirctType)
|
||||
|
||||
from .circt import ir
|
||||
from .circt.dialects import esi as raw_esi, hw, msft
|
||||
|
@ -473,6 +473,21 @@ class PureModule(Module):
|
|||
esi.ESIPureModuleParamOp(name, type_attr)
|
||||
|
||||
|
||||
@ServiceDecl
|
||||
class MMIO:
|
||||
"""ESI standard service to request access to an MMIO region."""
|
||||
|
||||
read = ServiceDecl.From(
|
||||
Bundle([
|
||||
BundledChannel("offset", ChannelDirection.TO, Bits(32)),
|
||||
BundledChannel("data", ChannelDirection.FROM, Bits(32))
|
||||
]))
|
||||
|
||||
@staticmethod
|
||||
def _op(sym_name: ir.StringAttr):
|
||||
return raw_esi.MMIOServiceDeclOp(sym_name)
|
||||
|
||||
|
||||
def package(sys: System):
|
||||
"""Package all ESI collateral."""
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
# RUN: rm -rf %t
|
||||
# RUN: %PYTHON% %s %t 2>&1 | FileCheck %s
|
||||
|
||||
from pycde import (Clock, Input, InputChannel, OutputChannel, Module, generator,
|
||||
types)
|
||||
from pycde import (Clock, Input, InputChannel, OutputChannel, Module, System,
|
||||
generator, types)
|
||||
from pycde import esi
|
||||
from pycde.common import AppID, Output, RecvBundle, SendBundle
|
||||
from pycde.constructs import Wire
|
||||
from pycde.esi import MMIO
|
||||
from pycde.types import (Bits, Bundle, BundledChannel, Channel,
|
||||
ChannelDirection, ChannelSignaling, UInt, ClockType)
|
||||
from pycde.testing import unittestmodule
|
||||
|
@ -126,3 +127,23 @@ class RecvBundleTest(Module):
|
|||
def build(self):
|
||||
to_channels = self.b_recv.unpack(resp=self.i1_in)
|
||||
self.s1_out = to_channels['req']
|
||||
|
||||
|
||||
# CHECK-LABEL: hw.module @MMIOReq()
|
||||
# CHECK-NEXT: %c0_i32 = hw.constant 0 : i32
|
||||
# CHECK-NEXT: %false = hw.constant false
|
||||
# CHECK-NEXT: [[B:%.+]] = esi.service.req.to_client <@MMIO::@read>(#esi.appid<"mmio_req">) : !esi.bundle<[!esi.channel<i32> to "offset", !esi.channel<i32> from "data"]>
|
||||
# CHECK-NEXT: %chanOutput, %ready = esi.wrap.vr %c0_i32, %false : i32
|
||||
# CHECK-NEXT: %offset = esi.bundle.unpack %chanOutput from [[B]] : !esi.bundle<[!esi.channel<i32> to "offset", !esi.channel<i32> from "data"]>
|
||||
@unittestmodule(esi_sys=True)
|
||||
class MMIOReq(Module):
|
||||
|
||||
@generator
|
||||
def build(ports):
|
||||
c32 = Bits(32)(0)
|
||||
c1 = Bits(1)(0)
|
||||
|
||||
read_bundle = MMIO.read(AppID("mmio_req"))
|
||||
|
||||
data, _ = Channel(Bits(32)).wrap(c32, c1)
|
||||
_ = read_bundle.unpack(data=data)
|
||||
|
|
|
@ -89,10 +89,9 @@ void MMIOServiceDeclOp::getPortList(SmallVectorImpl<ServicePortInfo> &ports) {
|
|||
ServicePortInfo::Direction::toClient,
|
||||
ChannelBundleType::get(
|
||||
ctxt,
|
||||
{BundledChannel{StringAttr::get(ctxt, "offset"),
|
||||
ChannelDirection::from,
|
||||
{BundledChannel{StringAttr::get(ctxt, "offset"), ChannelDirection::to,
|
||||
ChannelType::get(ctxt, IntegerType::get(ctxt, 32))},
|
||||
BundledChannel{StringAttr::get(ctxt, "data"), ChannelDirection::to,
|
||||
BundledChannel{StringAttr::get(ctxt, "data"), ChannelDirection::from,
|
||||
ChannelType::get(ctxt, IntegerType::get(ctxt, 32))}},
|
||||
/*resettable=*/UnitAttr())});
|
||||
// Write only port.
|
||||
|
@ -101,10 +100,9 @@ void MMIOServiceDeclOp::getPortList(SmallVectorImpl<ServicePortInfo> &ports) {
|
|||
ServicePortInfo::Direction::toClient,
|
||||
ChannelBundleType::get(
|
||||
ctxt,
|
||||
{BundledChannel{StringAttr::get(ctxt, "offset"),
|
||||
ChannelDirection::from,
|
||||
{BundledChannel{StringAttr::get(ctxt, "offset"), ChannelDirection::to,
|
||||
ChannelType::get(ctxt, IntegerType::get(ctxt, 32))},
|
||||
BundledChannel{StringAttr::get(ctxt, "data"), ChannelDirection::from,
|
||||
BundledChannel{StringAttr::get(ctxt, "data"), ChannelDirection::to,
|
||||
ChannelType::get(ctxt, IntegerType::get(ctxt, 32))}},
|
||||
/*resettable=*/UnitAttr())});
|
||||
}
|
||||
|
|
|
@ -205,11 +205,11 @@ hw.module @CallableAccel1(in %clk: !seq.clock, in %rst: i1) {
|
|||
}
|
||||
|
||||
esi.service.std.mmio @mmio
|
||||
!mmioReq = !esi.bundle<[!esi.channel<i32> from "offset", !esi.channel<i32> to "data"]>
|
||||
!mmioReq = !esi.bundle<[!esi.channel<i32> to "offset", !esi.channel<i32> from "data"]>
|
||||
|
||||
// CONN-LABEL: hw.module @MMIOManifest(in %clk : !seq.clock, in %rst : i1, in %manifest : !esi.bundle<[!esi.channel<i32> from "offset", !esi.channel<i32> to "data"]>) {
|
||||
// CONN-NEXT: esi.manifest.req #esi.appid<"manifest">, <@mmio::@read> std "esi.service.std.mmio", toClient, !esi.bundle<[!esi.channel<i32> from "offset", !esi.channel<i32> to "data"]>
|
||||
// CONN-NEXT: %data = esi.bundle.unpack %data from %manifest : !esi.bundle<[!esi.channel<i32> from "offset", !esi.channel<i32> to "data"]>
|
||||
// CONN-LABEL: hw.module @MMIOManifest(in %clk : !seq.clock, in %rst : i1, in %manifest : !esi.bundle<[!esi.channel<i32> to "offset", !esi.channel<i32> from "data"]>) {
|
||||
// CONN-NEXT: esi.manifest.req #esi.appid<"manifest">, <@mmio::@read> std "esi.service.std.mmio", toClient, !esi.bundle<[!esi.channel<i32> to "offset", !esi.channel<i32> from "data"]>
|
||||
// CONN-NEXT: %offset = esi.bundle.unpack %offset from %manifest : !esi.bundle<[!esi.channel<i32> to "offset", !esi.channel<i32> from "data"]>
|
||||
hw.module @MMIOManifest(in %clk: !seq.clock, in %rst: i1) {
|
||||
%req = esi.service.req.to_client <@mmio::@read> (#esi.appid<"manifest">) : !mmioReq
|
||||
%loopback = esi.bundle.unpack %loopback from %req : !mmioReq
|
||||
|
|
Loading…
Reference in New Issue