CIRCT 23.0.0git
Loading...
Searching...
No Matches
loopback.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, Signal, System, generator)
8from esiaccel.bsp import get_bsp
9from pycde.common import Constant
10from pycde.constructs import Wire
11from pycde.module import Metadata
12from pycde.signals import Struct
13from pycde.types import (Bits, Bundle, BundledChannel, Channel,
14 ChannelDirection, SInt, TypeAlias, UInt)
15from pycde import esi
16
17from esiaccel.esitester import SerialCoordTranslator
18
19SendI8 = Bundle([BundledChannel("send", ChannelDirection.FROM, Bits(8))])
20RecvI8 = Bundle([BundledChannel("recv", ChannelDirection.TO, Bits(8))])
21SendI0 = Bundle([BundledChannel("send", ChannelDirection.FROM, Bits(0))])
22RecvI0 = Bundle([BundledChannel("recv", ChannelDirection.TO, Bits(0))])
23
24
25@esi.ServiceDecl
27 Send = SendI8
28 Recv = RecvI8
29
30
31@esi.ServiceDecl
33 Send = SendI0
34 Recv = RecvI0
35
36
37class Loopback(Module):
38 clk = Clock()
39
40 metadata = Metadata(
41 name="LoopbackIP",
42 version="v0.0",
43 summary="IP which simply echos bytes",
44 misc={"foo": 1},
45 )
46
47 depth = Constant(UInt(32), 5)
48
49 @generator
50 def construct(ports):
51 data_in_bundle = HostComms.Recv(AppID("loopback_tohw"))
52 data_in = data_in_bundle.unpack()["recv"]
53
54 data_out_bundle = HostComms.Send(AppID("loopback_fromhw"))
55 data_out_bundle.unpack(send=data_in)
56
57 send_bundle = MyService.Recv(AppID("mysvc_recv"))
58 send_chan = send_bundle.unpack()["recv"]
59 sendi0_bundle = MyService.Send(AppID("mysvc_send"))
60 sendi0_bundle.unpack(send=send_chan)
61
62
63class ArgStruct(Struct):
64 a: UInt(16)
65 b: SInt(8)
66
67
68class ResultStruct(Struct):
69 x: SInt(8)
70 y: SInt(8)
71
72
73class OddInner(Struct):
74 p: UInt(8)
75 q: SInt(8)
76 r: UInt(8) * 2
77
78
79class OddStruct(Struct):
80 a: UInt(12)
81 b: SInt(7)
82 inner: OddInner
83
84
85class LoopbackStruct(Module):
86
87 @generator
88 def construct(ports):
89 result_wire = Wire(Channel(ResultStruct))
90 args = esi.FuncService.get_call_chans(AppID("structFunc"),
91 arg_type=ArgStruct,
92 result=result_wire)
93
94 ready = Wire(Bits(1))
95 arg_data, valid = args.unwrap(ready)
96 b_val = arg_data["b"]
97 b_plus_one = (b_val + SInt(8)(1)).as_sint(8)
98 result = ResultStruct(x=b_plus_one, y=b_val)
99 result_chan, result_ready = Channel(ResultStruct).wrap(result, valid)
100 ready.assign(result_ready)
101 result_wire.assign(result_chan)
102
103
104class LoopbackOddStruct(Module):
105
106 @generator
107 def construct(ports):
108 result_wire = Wire(Channel(OddStruct))
109 args = esi.FuncService.get_call_chans(AppID("oddStructFunc"),
110 arg_type=OddStruct,
111 result=result_wire)
112
113 ready = Wire(Bits(1))
114 arg_data, valid = args.unwrap(ready)
115 a_val = (arg_data["a"] + UInt(12)(1)).as_uint(12)
116 b_val = (arg_data["b"] + SInt(7)(-3)).as_sint(7)
117 inner = arg_data["inner"]
118 p_val = (inner["p"] + UInt(8)(5)).as_uint(8)
119 q_val = (inner["q"] + SInt(8)(2)).as_sint(8)
120 r0_val = (inner["r"][0] + UInt(8)(1)).as_uint(8)
121 r1_val = (inner["r"][1] + UInt(8)(2)).as_uint(8)
122 result = OddStruct(a=a_val,
123 b=b_val,
124 inner=OddInner(p=p_val, q=q_val, r=[r0_val, r1_val]))
125 result_chan, result_ready = Channel(OddStruct).wrap(result, valid)
126 ready.assign(result_ready)
127 result_wire.assign(result_chan)
128
129
130ArgArray = SInt(8) * 1
131ResultArray = TypeAlias(SInt(8) * 2, "ResultArray")
132
133
134class LoopbackArray(Module):
135
136 @generator
137 def construct(ports):
138 result_wire = Wire(Channel(ResultArray))
139 args = esi.FuncService.get_call_chans(AppID("arrayFunc"),
140 arg_type=ArgArray,
141 result=result_wire)
142
143 ready = Wire(Bits(1))
144 arg_data, valid = args.unwrap(ready)
145 elem = arg_data[0]
146 elem_plus_one = (elem + SInt(8)(1)).as_sint(8)
147 # ArrayCreate reverses element order; provide reversed list to match MLIR.
148 result_array = ResultArray([elem, elem_plus_one])
149 result_chan, result_ready = Channel(ResultArray).wrap(result_array, valid)
150 ready.assign(result_ready)
151 result_wire.assign(result_chan)
152
153
154MemA = esi.DeclareRandomAccessMemory(Bits(64), 20, name="MemA")
155
156
157class MemoryAccess1(Module):
158 clk = Clock()
159 rst = Reset()
160
161 @generator
162 def construct(ports):
163 MemA.instantiate_builtin(appid=AppID("mem"),
164 builtin="sv_mem",
165 result_types=[],
166 inputs=[ports.clk, ports.rst])
167
168 write_bundle = MemA.write(AppID("internal_write"))
169 write_req_type = MemA.write.type.req
170 write_req, _ = write_req_type.wrap(
171 {
172 "address": UInt(MemA.address_width)(0),
173 "data": Bits(64)(0)
174 },
175 Bits(1)(0))
176 write_bundle.unpack(req=write_req)
177
178
179class CallableFunc1(Module):
180
181 @generator
182 def construct(ports):
183 result_wire = Wire(Channel(UInt(16)))
184 args = esi.FuncService.get_call_chans(AppID("func1"),
185 arg_type=UInt(16),
186 result=result_wire)
187
188 ready = Wire(Bits(1))
189 _, valid = args.unwrap(ready)
190 result_chan, result_ready = Channel(UInt(16)).wrap(UInt(16)(0), valid)
191 ready.assign(result_ready)
192 result_wire.assign(result_chan)
193
194
195class LoopbackSInt4(Module):
196 """Loopback a si4 value: returns the input unchanged."""
197
198 @generator
199 def construct(ports):
200 result_wire = Wire(Channel(SInt(4)))
201 args = esi.FuncService.get_call_chans(AppID("sint4Func"),
202 arg_type=SInt(4),
203 result=result_wire)
204
205 ready = Wire(Bits(1))
206 arg_data, valid = args.unwrap(ready)
207 result_chan, result_ready = Channel(SInt(4)).wrap(arg_data, valid)
208 ready.assign(result_ready)
209 result_wire.assign(result_chan)
210
211
212class Top(Module):
213 clk = Clock()
214 rst = Reset()
215
216 @generator
217 def construct(ports):
218 Loopback(clk=ports.clk, appid=AppID("loopback_inst", 0))
219 Loopback(clk=ports.clk, appid=AppID("loopback_inst", 1))
220 MemoryAccess1(clk=ports.clk, rst=ports.rst)
227 clk=ports.clk,
228 rst=ports.rst,
229 instance_name="coord_translator_serial",
230 appid=AppID("coord_translator_serial"),
231 )
232
233
234if __name__ == "__main__":
235 bsp = get_bsp(sys.argv[2] if len(sys.argv) > 2 else None)
236 s = System(bsp(Top), name="Loopback", output_directory=sys.argv[1])
237 s.compile()
238 s.package()
239
240# CPP-TEST: depth: 0x5
241# CPP-TEST: loopback i8 ok: 0x5a
242# CPP-TEST: struct func ok: b=-7 x=-6 y=-7
243# CPP-TEST: odd struct func ok: a=2749 b=-20 p=10 q=-5 r0=4 r1=6
244# CPP-TEST: array func ok: -3 -2
245
246# QUERY-INFO: API version: 0
247# QUERY-INFO: ********************************
248# QUERY-INFO: * Module information
249# QUERY-INFO: ********************************
250# QUERY-INFO: - LoopbackIP v0.0
251# QUERY-INFO: IP which simply echos bytes
252# QUERY-INFO: Constants:
253# QUERY-INFO: depth: 5
254# QUERY-INFO: Extra metadata:
255# QUERY-INFO: foo: 1
256
257# QUERY-HIER: ********************************
258# QUERY-HIER: * Design hierarchy
259# QUERY-HIER: ********************************
260# QUERY-HIER: * Instance: {{.*}}
261# QUERY-HIER: * Ports:
262# QUERY-HIER: func1: function uint16(uint16)
263# QUERY-HIER: structFunc: function ResultStruct(ArgStruct)
264# QUERY-HIER: arrayFunc: function ResultArray(sint8[1])
265# QUERY-HIER: * Children:
266# QUERY-HIER: * Instance: loopback_inst[0]
267# QUERY-HIER: * Ports:
268# QUERY-HIER: loopback_tohw:
269# QUERY-HIER: recv: bits8
270# QUERY-HIER: loopback_fromhw:
271# QUERY-HIER: send: bits8
272# QUERY-HIER: mysvc_recv:
273# QUERY-HIER: recv: void
274# QUERY-HIER: mysvc_send:
275# QUERY-HIER: send: void
276# QUERY-HIER: * Instance: loopback_inst[1]
277# QUERY-HIER: * Ports:
278# QUERY-HIER: loopback_tohw:
279# QUERY-HIER: recv: bits8
280# QUERY-HIER: loopback_fromhw:
281# QUERY-HIER: send: bits8
282# QUERY-HIER: mysvc_recv:
283# QUERY-HIER: recv: void
284# QUERY-HIER: mysvc_send:
285# QUERY-HIER: send: void
286
287# LOOPBACK-H: /// Generated header for esi_system module LoopbackIP.
288# LOOPBACK-H-NEXT: #pragma once
289# LOOPBACK-H-NEXT: #include "types.h"
290# LOOPBACK-H-LABEL: namespace esi_system {
291# LOOPBACK-H-LABEL: class LoopbackIP {
292# LOOPBACK-H-NEXT: public:
293# LOOPBACK-H-NEXT: static constexpr uint32_t depth = 0x5;
294# LOOPBACK-H-NEXT: };
295# LOOPBACK-H-NEXT: } // namespace esi_system
return wrap(CMemoryType::get(unwrap(ctx), baseType, numElements))
construct(ports)
Definition loopback.py:217