cyclone_fpga/
lib.rs

1//! # fpga
2//!
3//! Rust traits to interact with FPGAs.
4//!
5//! Implemented for AWS F1 FPGAs.
6
7use core::marker::PhantomData;
8use thiserror::Error;
9
10pub mod align;
11pub use align::Aligned;
12
13#[cfg(feature = "f1")]
14pub mod f1;
15#[cfg(feature = "f1")]
16pub use f1::F1;
17
18pub mod null;
19pub use null::Null;
20
21#[derive(Debug, Error)]
22pub enum Error {
23    #[error("FPGA drivers require running as root.")]
24    SudoRequired,
25}
26
27pub type Result<T> = core::result::Result<T, Error>;
28
29/// Flush communications
30pub trait Flush {
31    /// flush communications
32    fn flush(&mut self);
33}
34
35/// Index-based writes to an FPGA.
36pub trait Write<V>: Flush {
37    /// write value to index
38    fn write(&mut self, index: usize, value: &V);
39}
40
41/// Index-based read/writes to an FPGA.
42pub trait ReadWrite<V>: Write<V> {
43    /// read value at index
44    fn read(&self, index: usize) -> V;
45}
46
47/// App-specific backoff mechanism used in streaming.
48pub trait Backoff<FPGA> {
49    fn backoff(fpga: &mut FPGA, offset: usize);
50}
51
52/// Streaming writes to an FPGA.
53///
54/// The backoff depends on the FPGA app's implementation of streaming.
55pub struct Stream<'a, P, FPGA: Write<P>, B = null::Backoff> {
56    fpga: &'a mut FPGA,
57    offset: usize,
58    __: PhantomData<(B, P)>,
59}
60
61/// Marker trait for FPGAs supporting streaming writes.
62pub trait Streamable<'a, P, B: Backoff<Self> = null::Backoff>: Sized + Write<P> {
63    /// initialize new stream
64    fn stream(&'a mut self, offset: usize) -> Stream<'a, P, Self, B>;
65}
66
67impl<'a, P, FPGA: Write<P>, B: Backoff<FPGA>> Streamable<'a, P, B> for FPGA {
68    fn stream(&'a mut self, offset: usize) -> Stream<'a, P, FPGA, B> {
69        Stream {
70            fpga: self,
71            offset,
72            __: PhantomData,
73        }
74    }
75}
76
77impl<'a, P, FPGA: Flush + Write<P>, B> Flush for Stream<'a, P, FPGA, B> {
78    fn flush(&mut self) {
79        self.fpga.flush()
80    }
81}
82
83impl<'a, P, FPGA: Write<P>, B> Stream<'a, P, FPGA, B> {
84    pub fn fpga(&mut self) -> &mut FPGA {
85        self.fpga
86    }
87
88    #[inline(always)]
89    pub fn offset(&self) -> usize {
90        self.offset
91    }
92}
93
94impl<'a, P, FPGA: Write<P>, B: Backoff<FPGA>> Stream<'a, P, FPGA, B> {
95    #[inline(always)]
96    pub fn write(&mut self, packet: &P) {
97        self.fpga.write(self.offset, packet);
98        self.offset += 1;
99        B::backoff(self.fpga, self.offset);
100    }
101}