sim_ring/
frame_gen.rs

1// Copyright (c) 2025 Graphcore Ltd. All rights reserved.
2
3use std::rc::Rc;
4
5use gwr_model_builder::EntityGet;
6use gwr_models::ethernet_frame::{DEST_MAC_BYTES, EthernetFrame, u64_to_mac};
7use gwr_track::entity::Entity;
8
9/// A frame Generator that can be used by the `Source` to produce frames on
10/// the fly.
11///
12/// This allows each frame being created to be unique which aids debug of the
13/// system.
14#[derive(EntityGet)]
15pub struct FrameGen {
16    entity: Rc<Entity>,
17    dest: [u8; DEST_MAC_BYTES],
18    payload_bytes: usize,
19    num_send_frames: usize,
20    num_sent_frames: usize,
21}
22
23impl FrameGen {
24    #[must_use]
25    pub fn new(
26        parent: &Rc<Entity>,
27        dest: [u8; DEST_MAC_BYTES],
28        payload_bytes: usize,
29        num_send_frames: usize,
30    ) -> Self {
31        Self {
32            entity: Rc::new(Entity::new(parent, &format!("gen_{dest:?}"))),
33            dest,
34            payload_bytes,
35            num_send_frames,
36            num_sent_frames: 0,
37        }
38    }
39}
40
41impl Iterator for FrameGen {
42    type Item = EthernetFrame;
43    fn next(&mut self) -> Option<Self::Item> {
44        if self.num_sent_frames < self.num_send_frames {
45            let label = self.num_sent_frames;
46            self.num_sent_frames += 1;
47
48            // Send to the correct `dest`, but set `src` to a unique value to aid debug
49            // (frame count).
50            Some(
51                EthernetFrame::new(&self.entity, self.payload_bytes)
52                    .set_dest(self.dest)
53                    .set_src(u64_to_mac(label as u64)),
54            )
55        } else {
56            None
57        }
58    }
59}