Skip to main content

luwen_api/chip/communication/
chip_interface.rs

1// SPDX-FileCopyrightText: © 2023 Tenstorrent Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::sync::Arc;
5
6use crate::{DeviceInfo, EthAddr};
7
8/// This trait is used to abstract the interface to the lowest level
9/// chip communication primitives. These primitives are defined to be a chip resource
10/// which requires exclusive access to safely use.
11///
12/// The implementation makes no attempt to use the borrow checker to enforce this exclusive access rule
13/// because the primary implementors of this trait will be C++ and Python code.
14pub trait ChipInterface: 'static {
15    /// Access information about the underlying chip.
16    fn get_device_info(&self) -> Result<Option<DeviceInfo>, Box<dyn std::error::Error>>;
17
18    /// Read and write to the noc endpoint on the chip in implementation
19    /// this may take the form of a direct pci bar read/write or a noc read/write
20    fn axi_read(&self, addr: u32, data: &mut [u8]) -> Result<(), Box<dyn std::error::Error>>;
21    fn axi_write(&self, addr: u32, data: &[u8]) -> Result<(), Box<dyn std::error::Error>>;
22
23    /// Read and write to a noc endpoint on the chip.
24    fn noc_read(
25        &self,
26        noc_id: u8,
27        x: u8,
28        y: u8,
29        addr: u64,
30        data: &mut [u8],
31    ) -> Result<(), Box<dyn std::error::Error>>;
32    fn noc_write(
33        &self,
34        noc_id: u8,
35        x: u8,
36        y: u8,
37        addr: u64,
38        data: &[u8],
39    ) -> Result<(), Box<dyn std::error::Error>>;
40    fn noc_broadcast(
41        &self,
42        noc_id: u8,
43        addr: u64,
44        data: &[u8],
45    ) -> Result<(), Box<dyn std::error::Error>>;
46    fn noc_multicast(
47        &self,
48        noc_id: u8,
49        start: (u8, u8),
50        end: (u8, u8),
51        addr: u64,
52        data: &[u8],
53    ) -> Result<(), Box<dyn std::error::Error>>;
54
55    /// Read and write to a noc endpoint via ethernet on a local or remote chip.
56    fn eth_noc_read(
57        &self,
58        eth_addr: EthAddr,
59        noc_id: u8,
60        x: u8,
61        y: u8,
62        addr: u64,
63        data: &mut [u8],
64    ) -> Result<(), Box<dyn std::error::Error>>;
65    fn eth_noc_write(
66        &self,
67        eth_addr: EthAddr,
68        noc_id: u8,
69        x: u8,
70        y: u8,
71        addr: u64,
72        data: &[u8],
73    ) -> Result<(), Box<dyn std::error::Error>>;
74    fn eth_noc_multicast(
75        &self,
76        eth_addr: EthAddr,
77        noc_id: u8,
78        start: (u8, u8),
79        end: (u8, u8),
80        addr: u64,
81        data: &[u8],
82    ) -> Result<(), Box<dyn std::error::Error>>;
83    fn eth_noc_broadcast(
84        &self,
85        eth_addr: EthAddr,
86        noc_id: u8,
87        addr: u64,
88        data: &[u8],
89    ) -> Result<(), Box<dyn std::error::Error>>;
90
91    fn as_any(&self) -> &dyn std::any::Any;
92}
93
94impl ChipInterface for Arc<dyn ChipInterface + Send + Sync> {
95    fn get_device_info(&self) -> Result<Option<DeviceInfo>, Box<dyn std::error::Error>> {
96        self.as_ref().get_device_info()
97    }
98
99    fn axi_read(&self, addr: u32, data: &mut [u8]) -> Result<(), Box<dyn std::error::Error>> {
100        self.as_ref().axi_read(addr, data)
101    }
102
103    fn axi_write(&self, addr: u32, data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
104        self.as_ref().axi_write(addr, data)
105    }
106
107    fn noc_read(
108        &self,
109        noc_id: u8,
110        x: u8,
111        y: u8,
112        addr: u64,
113        data: &mut [u8],
114    ) -> Result<(), Box<dyn std::error::Error>> {
115        self.as_ref().noc_read(noc_id, x, y, addr, data)
116    }
117
118    fn noc_write(
119        &self,
120        noc_id: u8,
121        x: u8,
122        y: u8,
123        addr: u64,
124        data: &[u8],
125    ) -> Result<(), Box<dyn std::error::Error>> {
126        self.as_ref().noc_write(noc_id, x, y, addr, data)
127    }
128
129    fn noc_multicast(
130        &self,
131        noc_id: u8,
132        start: (u8, u8),
133        end: (u8, u8),
134        addr: u64,
135        data: &[u8],
136    ) -> Result<(), Box<dyn std::error::Error>> {
137        self.as_ref().noc_multicast(noc_id, start, end, addr, data)
138    }
139
140    fn noc_broadcast(
141        &self,
142        noc_id: u8,
143        addr: u64,
144        data: &[u8],
145    ) -> Result<(), Box<dyn std::error::Error>> {
146        self.as_ref().noc_broadcast(noc_id, addr, data)
147    }
148
149    fn eth_noc_read(
150        &self,
151        eth_addr: EthAddr,
152        noc_id: u8,
153        x: u8,
154        y: u8,
155        addr: u64,
156        data: &mut [u8],
157    ) -> Result<(), Box<dyn std::error::Error>> {
158        self.as_ref()
159            .eth_noc_read(eth_addr, noc_id, x, y, addr, data)
160    }
161
162    fn eth_noc_write(
163        &self,
164        eth_addr: EthAddr,
165        noc_id: u8,
166        x: u8,
167        y: u8,
168        addr: u64,
169        data: &[u8],
170    ) -> Result<(), Box<dyn std::error::Error>> {
171        self.as_ref()
172            .eth_noc_write(eth_addr, noc_id, x, y, addr, data)
173    }
174
175    fn eth_noc_multicast(
176        &self,
177        eth_addr: EthAddr,
178        noc_id: u8,
179        start: (u8, u8),
180        end: (u8, u8),
181        addr: u64,
182        data: &[u8],
183    ) -> Result<(), Box<dyn std::error::Error>> {
184        self.as_ref()
185            .eth_noc_multicast(eth_addr, noc_id, start, end, addr, data)
186    }
187
188    fn eth_noc_broadcast(
189        &self,
190        eth_addr: EthAddr,
191        noc_id: u8,
192        addr: u64,
193        data: &[u8],
194    ) -> Result<(), Box<dyn std::error::Error>> {
195        self.as_ref()
196            .eth_noc_broadcast(eth_addr, noc_id, addr, data)
197    }
198
199    fn as_any(&self) -> &dyn std::any::Any {
200        self.as_ref().as_any()
201    }
202}
203
204pub struct NocInterface {
205    pub noc_id: u8,
206    pub x: u8,
207    pub y: u8,
208
209    pub backing: Box<dyn ChipInterface + Send + Sync>,
210}
211
212impl ChipInterface for NocInterface {
213    fn get_device_info(&self) -> Result<Option<DeviceInfo>, Box<dyn std::error::Error>> {
214        self.backing.get_device_info()
215    }
216
217    fn axi_read(&self, addr: u32, data: &mut [u8]) -> Result<(), Box<dyn std::error::Error>> {
218        self.backing
219            .noc_read(self.noc_id, self.x, self.y, addr as u64, data)
220    }
221
222    fn axi_write(&self, addr: u32, data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
223        self.backing
224            .noc_write(self.noc_id, self.x, self.y, addr as u64, data)
225    }
226
227    fn noc_read(
228        &self,
229        noc_id: u8,
230        x: u8,
231        y: u8,
232        addr: u64,
233        data: &mut [u8],
234    ) -> Result<(), Box<dyn std::error::Error>> {
235        self.backing.noc_read(noc_id, x, y, addr, data)
236    }
237
238    fn noc_write(
239        &self,
240        noc_id: u8,
241        x: u8,
242        y: u8,
243        addr: u64,
244        data: &[u8],
245    ) -> Result<(), Box<dyn std::error::Error>> {
246        self.backing.noc_write(noc_id, x, y, addr, data)
247    }
248
249    fn noc_multicast(
250        &self,
251        noc_id: u8,
252        start: (u8, u8),
253        end: (u8, u8),
254        addr: u64,
255        data: &[u8],
256    ) -> Result<(), Box<dyn std::error::Error>> {
257        self.backing.noc_multicast(noc_id, start, end, addr, data)
258    }
259
260    fn noc_broadcast(
261        &self,
262        noc_id: u8,
263        addr: u64,
264        data: &[u8],
265    ) -> Result<(), Box<dyn std::error::Error>> {
266        self.backing.noc_broadcast(noc_id, addr, data)
267    }
268
269    fn eth_noc_read(
270        &self,
271        eth_addr: EthAddr,
272        noc_id: u8,
273        x: u8,
274        y: u8,
275        addr: u64,
276        data: &mut [u8],
277    ) -> Result<(), Box<dyn std::error::Error>> {
278        self.backing
279            .eth_noc_read(eth_addr, noc_id, x, y, addr, data)
280    }
281
282    fn eth_noc_write(
283        &self,
284        eth_addr: EthAddr,
285        noc_id: u8,
286        x: u8,
287        y: u8,
288        addr: u64,
289        data: &[u8],
290    ) -> Result<(), Box<dyn std::error::Error>> {
291        self.backing
292            .eth_noc_write(eth_addr, noc_id, x, y, addr, data)
293    }
294
295    fn eth_noc_multicast(
296        &self,
297        eth_addr: EthAddr,
298        noc_id: u8,
299        start: (u8, u8),
300        end: (u8, u8),
301        addr: u64,
302        data: &[u8],
303    ) -> Result<(), Box<dyn std::error::Error>> {
304        self.backing
305            .eth_noc_multicast(eth_addr, noc_id, start, end, addr, data)
306    }
307
308    fn eth_noc_broadcast(
309        &self,
310        eth_addr: EthAddr,
311        noc_id: u8,
312        addr: u64,
313        data: &[u8],
314    ) -> Result<(), Box<dyn std::error::Error>> {
315        self.backing.eth_noc_broadcast(eth_addr, noc_id, addr, data)
316    }
317
318    fn as_any(&self) -> &dyn std::any::Any {
319        self
320    }
321}