CIRCT 24.0.0git
Loading...
Searching...
No Matches
hostmem_write.py
Go to the documentation of this file.
1# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5import sys
6
7from pycde import AppID, Clock, Module, Reset, System, esi, generator
8from pycde.constructs import Wire
9from pycde.types import Bits, StructType, UInt
10
11from esiaccel.bsp.common import TaggedWriteGearbox
12from esiaccel.bsp.cosim import CosimBSP
13
14
15def Writer(width):
16
17 class Writer(Module):
18 clk = Clock()
19 rst = Reset()
20
21 @generator
22 def build(ports):
23 req_type = esi.HostMem.write_req_channel_type(Bits(width))
24 wire_type = esi.HostMem.write_req_channel_type(Bits((width + 7) // 8 * 8))
25 req = esi.ChannelService.from_host(AppID("req"), wire_type)
26 req = req.transform(lambda r: req_type({
27 "address": r.address,
28 "tag": r.tag,
29 "data": r.data[:width],
30 }))
31 ack = esi.HostMem.write(AppID("host"), req)
32 gate = esi.ChannelService.from_host(AppID("gate"), UInt(8))
33 gate_data, gate_valid = gate.unwrap(Bits(1)(1))
34 enabled = gate_data.as_bits()[0].reg(ports.clk,
35 ports.rst,
36 ce=gate_valid,
37 name="enabled")
38 ready = Wire(Bits(1))
39 tag, valid = ack.unwrap(ready)
40 out, out_ready = ack.type.wrap(tag, valid & enabled)
41 ready.assign(out_ready & enabled)
42 esi.ChannelService.to_host(AppID("ack"), out)
43
44 return Writer
45
46
47def Top(bus_width):
48
49 class Top(Module):
50 clk = Clock()
51 rst = Reset()
52
53 @generator
54 def build(ports):
55 for width in [13, bus_width, bus_width + 24, bus_width * 2 + 24, 16384]:
56 Writer(width)(clk=ports.clk, rst=ports.rst, appid=AppID("wr", width))
57
58 window = esi.HostMem.write_window(Bits(24), 1)
59 req_type = StructType([("address", UInt(64)), ("data", Bits(24)),
60 ("last", UInt(8))])
61 req = esi.ChannelService.from_host(AppID("list_req"), req_type)
62 req = req.transform(lambda r: window.wrap(
63 window.lowered_type({
64 "address": r.address,
65 "tag": 0,
66 "data": [r.data],
67 "data_size": 0,
68 "last": r.last.as_bits()[0],
69 })))
70 ack = esi.HostMem.write(AppID("list_host"), req)
71 esi.ChannelService.to_host(AppID("list_ack"), ack)
72
73 # Observe the same gearbox independently to check exact beat counts,
74 # addresses, byte enables and payload-cap framing without timing asserts.
75 gearbox = TaggedWriteGearbox(16384, bus_width, max(256, bus_width // 8))
76 req = esi.ChannelService.from_host(AppID("probe_req"),
77 gearbox.in_.type.inner_type)
78 probe = gearbox(clk=ports.clk, rst=ports.rst, in_=req)
79 resp_type = StructType([("address", UInt(64)), ("tag", UInt(8)),
80 ("data", Bits(bus_width)),
81 ("valid_bytes", UInt(64)), ("last", UInt(8))])
82 resp = probe.out.transform(lambda r: resp_type({
83 "address": r.address,
84 "tag": r.tag,
85 "data": r.data,
86 "valid_bytes": r.valid_bytes.as_uint(64),
87 "last": r.last.as_uint(8),
88 }))
89 esi.ChannelService.to_host(AppID("probe_resp"), resp)
90
91 return Top
92
93
94if __name__ == "__main__":
95 bus_width = int(sys.argv[2]) if len(sys.argv) > 2 else 64
96 kwargs = {"hostmem_width": bus_width} if len(sys.argv) > 2 else {}
97 system = System(CosimBSP(Top(bus_width), **kwargs),
98 name="HostMemWrite",
99 output_directory=sys.argv[1])
100 system.compile()
101 system.package()
Top(bus_width)