bloqade_lanes_bytecode_core/arch/
addr.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[repr(u8)]
9pub enum Direction {
10 Forward = 0,
12 Backward = 1,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18#[repr(u8)]
19pub enum MoveType {
20 SiteBus = 0,
22 WordBus = 1,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
32pub struct LocationAddr {
33 pub word_id: u32,
34 pub site_id: u32,
35}
36
37impl LocationAddr {
38 pub fn encode(&self) -> u32 {
42 ((self.word_id as u16 as u32) << 16) | (self.site_id as u16 as u32)
43 }
44
45 pub fn decode(bits: u32) -> Self {
47 Self {
48 word_id: (bits >> 16) & 0xFFFF,
49 site_id: bits & 0xFFFF,
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
63pub struct LaneAddr {
64 pub direction: Direction,
65 pub move_type: MoveType,
66 pub word_id: u32,
67 pub site_id: u32,
68 pub bus_id: u32,
69}
70
71impl LaneAddr {
72 pub fn encode(&self) -> (u32, u32) {
74 let data0 = ((self.word_id as u16 as u32) << 16) | (self.site_id as u16 as u32);
75 let data1 = ((self.direction as u32) << 31)
76 | ((self.move_type as u32) << 30)
77 | (self.bus_id as u16 as u32);
78 (data0, data1)
79 }
80
81 pub fn encode_u64(&self) -> u64 {
83 let (d0, d1) = self.encode();
84 (d0 as u64) | ((d1 as u64) << 32)
85 }
86
87 pub fn decode(data0: u32, data1: u32) -> Self {
89 let direction = if (data1 >> 31) & 1 == 0 {
90 Direction::Forward
91 } else {
92 Direction::Backward
93 };
94 let move_type = if (data1 >> 30) & 1 == 0 {
95 MoveType::SiteBus
96 } else {
97 MoveType::WordBus
98 };
99 Self {
100 direction,
101 move_type,
102 word_id: (data0 >> 16) & 0xFFFF,
103 site_id: data0 & 0xFFFF,
104 bus_id: data1 & 0xFFFF,
105 }
106 }
107
108 pub fn decode_u64(bits: u64) -> Self {
110 Self::decode(bits as u32, (bits >> 32) as u32)
111 }
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
120pub struct ZoneAddr {
121 pub zone_id: u32,
122}
123
124impl ZoneAddr {
125 pub fn encode(&self) -> u32 {
127 self.zone_id as u16 as u32
128 }
129
130 pub fn decode(bits: u32) -> Self {
132 Self {
133 zone_id: bits & 0xFFFF,
134 }
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141
142 #[test]
143 fn test_location_addr_round_trip() {
144 let addr = LocationAddr {
145 word_id: 0xABCD,
146 site_id: 0x1234,
147 };
148 let bits = addr.encode();
149 assert_eq!(bits, 0xABCD_1234);
150 assert_eq!(LocationAddr::decode(bits), addr);
151 }
152
153 #[test]
154 fn test_location_addr_zero() {
155 let addr = LocationAddr {
156 word_id: 0,
157 site_id: 0,
158 };
159 assert_eq!(addr.encode(), 0);
160 assert_eq!(LocationAddr::decode(0), addr);
161 }
162
163 #[test]
164 fn test_lane_addr_round_trip() {
165 let addr = LaneAddr {
166 direction: Direction::Backward,
167 move_type: MoveType::WordBus,
168 word_id: 0x1234,
169 site_id: 0x5678,
170 bus_id: 0x9ABC,
171 };
172 let (data0, data1) = addr.encode();
173 assert_eq!(LaneAddr::decode(data0, data1), addr);
174
175 assert_eq!((data0 >> 16) & 0xFFFF, 0x1234); assert_eq!(data0 & 0xFFFF, 0x5678); assert_eq!((data1 >> 31) & 1, 1); assert_eq!((data1 >> 30) & 1, 1); assert_eq!(data1 & 0xFFFF, 0x9ABC); }
184
185 #[test]
186 fn test_lane_addr_forward_sitebus() {
187 let addr = LaneAddr {
188 direction: Direction::Forward,
189 move_type: MoveType::SiteBus,
190 word_id: 0,
191 site_id: 0,
192 bus_id: 1,
193 };
194 let (data0, data1) = addr.encode();
195 assert_eq!(data0, 0);
196 assert_eq!(data1, 1);
197 assert_eq!(LaneAddr::decode(data0, data1), addr);
198 }
199
200 #[test]
201 fn test_lane_addr_u64_round_trip() {
202 let addr = LaneAddr {
203 direction: Direction::Backward,
204 move_type: MoveType::WordBus,
205 word_id: 1,
206 site_id: 0,
207 bus_id: 0,
208 };
209 let packed = addr.encode_u64();
210 assert_eq!(LaneAddr::decode_u64(packed), addr);
211 }
212
213 #[test]
214 fn test_zone_addr_round_trip() {
215 let addr = ZoneAddr { zone_id: 42 };
216 let bits = addr.encode();
217 assert_eq!(bits, 42);
218 assert_eq!(ZoneAddr::decode(bits), addr);
219 }
220
221 #[test]
222 fn test_zone_addr_max() {
223 let addr = ZoneAddr { zone_id: 0xFFFF };
224 let bits = addr.encode();
225 assert_eq!(bits, 0xFFFF);
226 assert_eq!(ZoneAddr::decode(bits), addr);
227 }
228}