CIRCT 24.0.0git
Loading...
Searching...
No Matches
backpressure.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
5# Hardware for the cosim backpressure integration tests.
6#
7# * GatedLoopback ("loopback"): loops `in` back to `out`, but only while the
8# last message on `gate` was non-zero. With the gate closed, `in` is never
9# consumed, so host writes back up (host -> simulation backpressure).
10#
11# * Producer ("producer"): a `produce` command with N makes it emit 0..N-1 on
12# `stream` as fast as the host side accepts them. A message on `query`
13# returns, on `sent`, how many it has emitted so far. That lets the host
14# observe that the producer was stalled by an unread `stream` (simulation ->
15# host backpressure) rather than having buffered everything host-side.
16
17import sys
18
19from pycde import AppID, Clock, Module, Reset, System, esi, generator
20from pycde.constructs import Counter, Wire
21from pycde.types import Bits, Channel, UInt
22
23from esiaccel.bsp import get_bsp
24
25
27 clk = Clock()
28 rst = Reset()
29
30 @generator
31 def build(ports):
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
39 inp = esi.ChannelService.from_host(AppID("in"), UInt(32))
40 in_ready = Wire(Bits(1))
41 data, valid = inp.unwrap(in_ready)
42 out, out_ready = Channel(UInt(32)).wrap(data, valid & enabled)
43 in_ready.assign(out_ready & enabled)
44 esi.ChannelService.to_host(AppID("out"), out)
45
46
48 clk = Clock()
49 rst = Reset()
50
51 @generator
52 def build(ports):
53 produce = esi.ChannelService.from_host(AppID("produce"), UInt(32))
54 count, count_valid = produce.unwrap(Bits(1)(1))
55 target = count.reg(ports.clk, ports.rst, ce=count_valid, name="target")
56
57 xact = Wire(Bits(1))
58 sent = Counter(32)(clk=ports.clk,
59 rst=ports.rst,
60 clear=Bits(1)(0),
61 increment=xact)
62 valid = sent.out < target
63 stream, stream_ready = Channel(UInt(32)).wrap(sent.out, valid)
64 xact.assign(valid & stream_ready)
65 esi.ChannelService.to_host(AppID("stream"), stream)
66
67 query = esi.ChannelService.from_host(AppID("query"), UInt(8))
68 query_ready = Wire(Bits(1))
69 _, query_valid = query.unwrap(query_ready)
70 resp, resp_ready = Channel(UInt(32)).wrap(sent.out, query_valid)
71 query_ready.assign(resp_ready)
72 esi.ChannelService.to_host(AppID("sent"), resp)
73
74
75class Top(Module):
76 clk = Clock()
77 rst = Reset()
78
79 @generator
80 def build(ports):
81 GatedLoopback(clk=ports.clk, rst=ports.rst, appid=AppID("loopback"))
82 Producer(clk=ports.clk, rst=ports.rst, appid=AppID("producer"))
83
84
85if __name__ == "__main__":
86 bsp = get_bsp(sys.argv[2] if len(sys.argv) > 2 else None)
87 s = System(bsp(Top), name="BackpressureTest", output_directory=sys.argv[1])
88 s.compile()
89 s.package()
return wrap(CMemoryType::get(unwrap(ctx), baseType, numElements))