sim_ring/
frame_gen.rs

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