gwr_models/memory/
memory_access.rs1use std::fmt::Display;
4use std::rc::Rc;
5
6use gwr_engine::sim_error;
7use gwr_engine::traits::{Routable, SimObject, TotalBytes};
8use gwr_engine::types::{AccessType, SimError};
9use gwr_track::entity::Entity;
10use gwr_track::id::Unique;
11use gwr_track::{Id, create_id, track_create_object};
12
13use crate::memory::CacheHintType;
14use crate::memory::memory_map::DeviceId;
15use crate::memory::traits::{AccessMemory, ReadMemory};
16
17#[derive(Clone, Debug)]
18pub struct MemoryAccess {
19 created_by: Rc<Entity>,
20 id: Id,
21 access_type: AccessType,
22 access_size_bytes: usize,
23 dst_addr: u64,
24 src_addr: u64,
25 dst_device: DeviceId,
26 src_device: DeviceId,
27 cache_hint: CacheHintType,
28
29 overhead_size_bytes: usize,
31}
32
33impl Display for MemoryAccess {
34 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
35 write!(
36 f,
37 "{}: {}@{:x}",
38 self.access_type, self.access_size_bytes, self.dst_addr
39 )
40 }
41}
42
43impl TotalBytes for MemoryAccess {
44 fn total_bytes(&self) -> usize {
45 match self.access_type {
46 AccessType::Control | AccessType::ReadRequest | AccessType::WriteNonPostedResponse => {
47 self.overhead_size_bytes
48 }
49 AccessType::WriteRequest
50 | AccessType::WriteNonPostedRequest
51 | AccessType::ReadResponse => self.access_size_bytes + self.overhead_size_bytes,
52 }
53 }
54}
55
56impl Unique for MemoryAccess {
57 fn id(&self) -> Id {
58 self.id
59 }
60}
61
62impl AccessMemory for MemoryAccess {
63 fn dst_addr(&self) -> u64 {
64 self.dst_addr
65 }
66
67 fn src_addr(&self) -> u64 {
68 self.src_addr
69 }
70
71 fn dst_device(&self) -> DeviceId {
72 self.dst_device
73 }
74
75 fn src_device(&self) -> DeviceId {
76 self.src_device
77 }
78
79 fn cache_hint(&self) -> CacheHintType {
80 CacheHintType::Allocate
81 }
82
83 fn access_size_bytes(&self) -> usize {
84 self.access_size_bytes
85 }
86
87 fn to_response(&self, _mem: &impl ReadMemory) -> Result<Self, SimError> {
88 let response_type = match self.access_type {
89 AccessType::Control => AccessType::Control,
90 AccessType::ReadRequest => AccessType::ReadResponse,
91 AccessType::WriteNonPostedRequest => AccessType::WriteNonPostedResponse,
92 AccessType::ReadResponse
93 | AccessType::WriteNonPostedResponse
94 | AccessType::WriteRequest => {
95 return sim_error!("{}: unsupported by to_response()", self.access_type);
96 }
97 };
98 Ok(MemoryAccess {
99 created_by: self.created_by.clone(),
100 id: self.id,
101 access_type: response_type,
102 access_size_bytes: self.access_size_bytes,
103 dst_addr: self.dst_addr,
104 src_addr: self.src_addr,
105 dst_device: self.src_device,
106 src_device: self.dst_device,
107 cache_hint: self.cache_hint,
108 overhead_size_bytes: self.overhead_size_bytes,
109 })
110 }
111}
112
113impl Routable for MemoryAccess {
114 fn destination(&self) -> u64 {
115 self.dst_device.0
117 }
118 fn access_type(&self) -> AccessType {
119 self.access_type
120 }
121}
122
123impl MemoryAccess {
124 #[must_use]
125 #[expect(clippy::too_many_arguments)]
126 pub fn new(
127 created_by: &Rc<Entity>,
128 access_type: AccessType,
129 access_size_bytes: usize,
130 dst_addr: u64,
131 src_addr: u64,
132 dst_device: DeviceId,
133 src_device: DeviceId,
134 overhead_size_bytes: usize,
135 ) -> Self {
136 let access = Self {
137 created_by: created_by.clone(),
138 id: create_id!(created_by),
139 access_size_bytes,
140 access_type,
141 dst_addr,
142 src_addr,
143 dst_device,
144 src_device,
145 cache_hint: CacheHintType::Allocate,
146 overhead_size_bytes,
147 };
148 track_create_object!(
149 created_by;
150 access.id,
151 access.total_bytes(),
152 "bytes",
153 access.access_type() as u8,
154 "MemoryAccess: {access}"
155 );
156 access
157 }
158}
159
160impl SimObject for MemoryAccess {}