gwr_components/
connect.rs

1// Copyright (c) 2023 Graphcore Ltd. All rights reserved.
2
3//! Helper connection macros
4
5#[doc(hidden)]
6pub use paste::paste;
7
8/// Connect an [OutPort](gwr_engine::port::OutPort) port to an
9/// [InPort](gwr_engine::port::InPort)
10#[macro_export]
11macro_rules! connect_port {
12    ($from:expr, $from_port_name:ident => $to:expr, $to_port_name:ident) => {
13        {
14            gwr_track::debug!($from.entity() ; "Connect {}.{} => {}.{}", $from, stringify!($from_port_name), $to, stringify!($to_port_name));
15            $crate::connect::paste! {
16                $from.[< connect_port_ $from_port_name >]($to.[< port_ $to_port_name >]())
17            }
18        }
19    };
20    ($from:expr, $from_port_name:ident, $from_index:expr => $to:expr, $to_port_name:ident) => {
21        {
22            let from_index: usize = $from_index;
23            gwr_track::debug!($from.entity() ; "Connect {}.{}[{}] => {}.{}", $from, stringify!($from_port_name), from_index, $to, stringify!($to_port_name));
24            $crate::connect::paste! {
25                $from.[< connect_port_ $from_port_name _i >](from_index, $to.[< port_ $to_port_name >]())
26            }
27        }
28    };
29    ($from:expr, $from_port_name:ident => $to:expr, $to_port_name:ident, $to_index:expr) => {
30        {
31            let to_index: usize = $to_index;
32            gwr_track::debug!($from.entity() ; "Connect {}.{} => {}.{}[{}]", $from, stringify!($from_port_name), $to, stringify!($to_port_name), to_index);
33            $crate::connect::paste! {
34                $from.[< connect_port_ $from_port_name >]($to.[< port_ $to_port_name _i >](to_index))
35            }
36        }
37    };
38    ($from:expr, $from_port_name:ident, $from_index:expr => $to:expr, $to_port_name:ident, $to_index:expr) => {
39        {
40            let from_index: usize = $from_index;
41            let to_index: usize = $to_index;
42            gwr_track::debug!($from.entity() ; "Connect {}.{}[{}] => {}.{}[{}]", $from, stringify!($from_port_name), from_index, $to, stringify!($to_port_name), to_index);
43            $crate::connect::paste! {
44                $from.[< connect_port_ $from_port_name _i >](from_index, $to.[< port_ $to_port_name _i >](to_index))
45            }
46        }
47    };
48}
49
50/// Create and connect a dummy RX port
51#[macro_export]
52macro_rules! connect_dummy_rx {
53    ($from:expr, $from_port_name:ident => $engine:expr, $clock:expr, $entity:expr) => {
54        {
55            use gwr_track::entity::GetEntity;
56            let rx_port = gwr_engine::port::InPort::new($engine, $clock, $entity, "dummy");
57
58            gwr_track::debug!($from.entity() ; "Connect {}.{} => {}", $from, stringify!($from_port_name), rx_port);
59            $crate::connect::paste! {
60                $from.[< connect_port_ $from_port_name >](rx_port.state())
61            }
62        }
63    };
64    ($from:expr, $from_port_name:ident, $from_index:expr => $engine:expr, $clock:expr, $entity:expr) => {
65        {
66            use gwr_track::entity::GetEntity;
67            let rx_port = gwr_engine::port::InPort::new($engine, $clock, $entity, "dummy");
68
69            let from_index: usize = $from_index;
70            gwr_track::debug!($from.entity() ; "Connect {}.{}[{}] => {}", $from, stringify!($from_port_name), from_index, rx_port);
71            $crate::connect::paste! {
72                $from.[< connect_port_ $from_port_name _i >](from_index, rx_port.state())
73            }
74        }
75    };
76}
77
78/// Create and connect a dummy TX port
79#[macro_export]
80macro_rules! connect_dummy_tx {
81    ($entity:expr => $to:expr, $to_port_name:ident) => {
82        {
83            let mut tx_port = gwr_engine::port::OutPort::new($entity, "dummy");
84
85            gwr_track::debug!($entity ; "Connect {} => {}.{}", tx_port, $to, stringify!($to_port_name));
86            $crate::connect::paste! {
87                tx_port.connect($to.[< port_ $to_port_name >]())
88            }
89        }
90    };
91    ($entity:expr => $to:expr, $to_port_name:ident, $to_index:expr) => {
92        {
93            let mut tx_port = gwr_engine::port::OutPort::new($entity, "dummy");
94
95            let to_index: usize = $to_index;
96            gwr_track::debug!($entity ; "Connect {} => {}.{}[{}]", tx_port, $to, stringify!($to_port_name), to_index);
97            $crate::connect::paste! {
98                tx_port.connect($to.[< port_ $to_port_name _i >](to_index))
99            }
100        }
101    };
102}
103
104/// Connect a tx port for a subcomponent.
105///
106/// The subcomponent is expected to be stored in a `RefCell<Option<>>`
107#[macro_export]
108macro_rules! connect_tx {
109    ($component:expr, $fn:ident ; $port_state:ident) => {
110        $crate::connect::paste! {
111            $component
112                .borrow_mut()
113                .as_mut()
114                .unwrap()
115                .$fn($port_state)
116        }
117    };
118}
119
120/// Connect a tx port for a subcomponent where the port is one of an array.
121///
122/// The subcomponent is expected to be stored in a `RefCell<Option<>>`
123#[macro_export]
124macro_rules! connect_tx_i {
125    ($component:expr, $fn:ident, $index:expr ; $port_state:ident) => {
126        $component
127            .borrow_mut()
128            .as_mut()
129            .unwrap()
130            .$fn($index, $port_state)
131    };
132}
133
134/// Access rx port for a subcomponent.
135///
136/// The subcomponent is expected to be stored in a `RefCell<Option<>>`
137#[macro_export]
138macro_rules! port_rx {
139    ($component:expr, $fn:ident) => {
140        $component.borrow().as_ref().unwrap().$fn()
141    };
142}
143
144/// Access an individual index of an rx port array for a subcomponent.
145///
146/// The subcomponent is expected to be stored in a `RefCell<Option<>>`
147#[macro_export]
148macro_rules! port_rx_i {
149    ($component:expr, $fn:ident, $index:expr) => {
150        $component.borrow().as_ref().unwrap().$fn($index)
151    };
152}
153
154/// Get a reference to a variable stored in a `RefCell<Option<>>`.
155#[macro_export]
156macro_rules! borrow_option {
157    ($var:expr) => {
158        $var.borrow().as_ref().unwrap()
159    };
160}
161
162/// Get a mutable reference to a variable stored in a `RefCell<Option<>>`.
163#[macro_export]
164macro_rules! borrow_option_mut {
165    ($var:expr) => {
166        $var.borrow_mut().as_mut().unwrap()
167    };
168}
169
170/// Take a variable out of a `RefCell<Option<>>`.
171#[macro_export]
172macro_rules! take_option {
173    ($var:expr) => {
174        $var.borrow_mut().take().unwrap()
175    };
176}