Skip to content

Commit

Permalink
[ESI] MMIO read service implementation in PyCDE (#7306)
Browse files Browse the repository at this point in the history
Implements a channel-based MMIO read service generator. Changes the offset type on the MMIO std service to `ui32` from `i32`.
  • Loading branch information
teqdruid authored Jul 12, 2024
1 parent cdfcd96 commit 34263bd
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 138 deletions.
34 changes: 29 additions & 5 deletions frontends/PyCDE/integration_test/esi_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
# RUN: esi-cosim.py -- %PYTHON% %S/test_software/esi_test.py cosim env

import pycde
from pycde import (AppID, Clock, Input, Module, generator)
from pycde import (AppID, Clock, Module, Reset, modparams, generator)
from pycde.bsp import cosim
from pycde.constructs import Wire
from pycde.esi import FuncService
from pycde.types import (Bits, Bundle, BundledChannel, Channel,
ChannelDirection, UInt)
from pycde.esi import FuncService, MMIO
from pycde.types import (Bits, Channel, UInt)

import sys

Expand All @@ -33,13 +32,38 @@ def construct(ports):
loopback.assign(data_chan)


@modparams
def MMIOClient(add_amt: int):

class MMIOClient(Module):
"""A module which requests an MMIO address space and upon an MMIO read
request, returns the <address offset into its space> + add_amt."""

@generator
def build(ports):
mmio_read_bundle = MMIO.read(appid=AppID("mmio_client", add_amt))

address_chan_wire = Wire(Channel(UInt(32)))
address, address_valid = address_chan_wire.unwrap(1)
response_data = (address.as_uint() + add_amt).as_bits(64)
response_chan, response_ready = Channel(Bits(64)).wrap(
response_data, address_valid)

address_chan = mmio_read_bundle.unpack(data=response_chan)['offset']
address_chan_wire.assign(address_chan)

return MMIOClient


class Top(Module):
clk = Clock()
rst = Input(Bits(1))
rst = Reset()

@generator
def construct(ports):
LoopbackInOutAdd7()
for i in range(4, 18, 5):
MMIOClient(i)()


if __name__ == "__main__":
Expand Down
37 changes: 36 additions & 1 deletion frontends/PyCDE/integration_test/test_software/esi_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,40 @@

mmio = acc.get_service_mmio()
data = mmio.read(8)
print(f"mmio data@8: {data:X}")
assert data == 0x207D98E5E5100E51

################################################################################
# MMIOClient tests
################################################################################


def read_offset(mmio_offset: int, offset: int, add_amt: int):
data = mmio.read(mmio_offset + offset)
if data == add_amt + offset:
print(f"PASS: read_offset({mmio_offset}, {offset}, {add_amt}) -> {data}")
else:
assert False, f"read_offset({mmio_offset}, {offset}, {add_amt}) -> {data}"


# MMIO offset into mmio_client[9]. TODO: get this from the manifest. API coming.
mmio_client_9_offset = 131072
read_offset(mmio_client_9_offset, 0, 9)
read_offset(mmio_client_9_offset, 13, 9)

# MMIO offset into mmio_client[4].
mmio_client_4_offset = 65536
read_offset(mmio_client_4_offset, 0, 4)
read_offset(mmio_client_4_offset, 13, 4)

# MMIO offset into mmio_client[14].
mmio_client_14_offset = 196608
read_offset(mmio_client_14_offset, 0, 14)
read_offset(mmio_client_14_offset, 13, 14)

################################################################################
# Manifest tests
################################################################################

assert acc.sysinfo().esi_version() == 0
m = acc.manifest()
assert m.api_version == 0
Expand All @@ -23,6 +54,10 @@
send = d.ports[esi.AppID("loopback_add7")].write_port("arg")
send.connect()

################################################################################
# Loopback add 7 tests
################################################################################

data = 10234
send.write(data)
got_data = False
Expand Down
Loading

0 comments on commit 34263bd

Please sign in to comment.