From 2457116fc0f77fff9bad814cb0c810a665cdf6ea Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 10 Mar 2026 21:23:47 -0700 Subject: [PATCH] WIP: adding memory_interface_adapter_no_split --- crates/cpu/src/main_memory_and_io.rs | 988 ++- .../cpu/src/main_memory_and_io/simple_uart.rs | 14 +- .../memory_interface_adapter_no_split.vcd | 7184 +++++++++++++++++ crates/cpu/tests/memory_interface.rs | 660 ++ crates/cpu/tests/simple_uart.rs | 8 +- 5 files changed, 8841 insertions(+), 13 deletions(-) create mode 100644 crates/cpu/tests/expected/memory_interface_adapter_no_split.vcd create mode 100644 crates/cpu/tests/memory_interface.rs diff --git a/crates/cpu/src/main_memory_and_io.rs b/crates/cpu/src/main_memory_and_io.rs index af35662..1c0b18c 100644 --- a/crates/cpu/src/main_memory_and_io.rs +++ b/crates/cpu/src/main_memory_and_io.rs @@ -2,12 +2,27 @@ // See Notices.txt for copyright information use crate::{config::CpuConfig, next_pc::FETCH_BLOCK_ID_WIDTH, util::array_vec::ArrayVec}; -use fayalite::{prelude::*, util::ready_valid::ReadyValid}; -use std::num::{NonZeroU64, NonZeroUsize, Wrapping}; +use fayalite::{ + bundle::BundleType, + expr::Valueless, + int::UIntInRangeType, + intern::{Intern, Interned}, + module::{instance_with_loc, wire_with_loc}, + prelude::*, + util::{ + prefix_sum, + ready_valid::{ReadyValid, queue}, + }, +}; +use std::{ + cmp::Ordering, + fmt, + num::{NonZeroU64, NonZeroUsize, Wrapping}, +}; pub mod simple_uart; -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)] pub enum AddressRange { Full, Limited { @@ -16,6 +31,19 @@ pub enum AddressRange { }, } +impl fmt::Debug for AddressRange { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Full => write!(f, "Full"), + Self::Limited { start, size } => f + .debug_struct("Limited") + .field("start", &fmt::from_fn(|f| write!(f, "{start:#x}"))) + .field("size", &fmt::from_fn(|f| write!(f, "{size:#x}"))) + .finish(), + } + } +} + impl AddressRange { pub const fn from_wrapping_range_inclusive(range: std::ops::RangeInclusive) -> Self { let start = Wrapping(*range.start()); @@ -118,6 +146,21 @@ impl MemoryInterfaceConfig { address_range: AddressRange::Full, } } + #[track_caller] + pub const fn new( + log2_bus_width_in_bytes: u8, + queue_capacity: usize, + op_id_width: usize, + address_range: AddressRange, + ) -> Self { + Self { + log2_bus_width_in_bytes, + queue_capacity: NonZeroUsize::new(queue_capacity) + .expect("queue capacity must be at least 1"), + op_id_width, + address_range, + } + } pub const fn bus_width_in_bytes(&self) -> usize { 1usize.strict_shl(self.log2_bus_width_in_bytes as u32) } @@ -180,6 +223,7 @@ pub struct MemoryOperationFinish> { #[hdl(no_static)] pub struct MemoryInterface> { pub start: ReadyValid>, + /// started operations must finish in the same order they started in #[hdl(flip)] pub finish: ReadyValid>, /// for debugging @@ -187,3 +231,941 @@ pub struct MemoryInterface> { pub next_op_ids: HdlOption, MemoryInterfaceQueueCapacity>>, pub config: C, } + +pub const fn memory_interface_always_error_config( + base_config: MemoryInterfaceConfig, +) -> MemoryInterfaceConfig { + let MemoryInterfaceConfig { + log2_bus_width_in_bytes, + queue_capacity: _, + op_id_width, + address_range: _, + } = base_config; + MemoryInterfaceConfig { + log2_bus_width_in_bytes, + queue_capacity: const { NonZeroUsize::new(1).unwrap() }, + op_id_width, + address_range: AddressRange::Full, + } +} + +#[hdl_module] +pub fn memory_interface_always_error(config: PhantomConst) { + assert_eq!( + *config.get(), + memory_interface_always_error_config(*config.get()), + ); + #[hdl] + let input_interface: MemoryInterface> = + m.input(MemoryInterface[config]); + + connect( + input_interface.next_op_ids, + input_interface.ty().next_op_ids.HdlNone(), + ); + connect(input_interface.start.ready, input_interface.finish.ready); + connect( + input_interface.finish.data, + input_interface.ty().finish.data.HdlNone(), + ); + #[hdl] + if let HdlSome(_) = input_interface.start.data { + connect( + input_interface.finish.data, + HdlSome( + #[hdl] + MemoryOperationFinish::<_> { + kind: MemoryOperationFinishKind.Error(MemoryOperationErrorKind.Generic()), + read_data: repeat(0u8, MemoryInterfaceBusWidthInBytes[config]), + config, + }, + ), + ); + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct MemoryInterfacesBundleFieldPath(pub Interned<[Interned]>); + +impl MemoryInterfacesBundleFieldPath { + pub fn from_slice(path: &[Interned]) -> Self { + Self(path.intern()) + } +} + +impl fmt::Display for MemoryInterfacesBundleFieldPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.0.is_empty() { + return f.write_str(""); + } + for (i, name) in self.0.iter().enumerate() { + if i != 0 { + f.write_str(".")?; + } + if name.is_empty() || name.contains(|ch: char| !ch.is_ascii_alphanumeric() && ch != '_') + { + write!(f, "{name:?}")?; + } else { + f.write_str(name)?; + } + } + Ok(()) + } +} + +impl fmt::Debug for MemoryInterfacesBundleFieldPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct MemoryInterfacesBundleField< + T: ValueType>>, +> { + pub path: MemoryInterfacesBundleFieldPath, + pub value: T, +} + +#[derive(Clone, Debug)] +pub struct MemoryInterfacesBundleProperties< + T: ValueType>>, +> { + first_full_interface: Option, + fields: Vec>, +} + +impl>>> + MemoryInterfacesBundleProperties +{ + pub fn first_full_interface(&self) -> Option { + self.first_full_interface + } + pub fn fields(&self) -> &[MemoryInterfacesBundleField] { + &self.fields + } + pub fn into_fields(self) -> Vec> { + self.fields + } + #[track_caller] + pub fn from_fields(fields: Vec>) -> Self { + let mut first_full_interface = None; + for (index, field) in fields.iter().enumerate() { + let ty = field.value.ty(); + assert_eq!( + ty, MemoryInterface[ty.config], + "inconsistent field type: {}", + field.path, + ); + if let None = first_full_interface + && let AddressRange::Full = ty.config.get().address_range + { + first_full_interface = Some(index); + } + } + Self { + first_full_interface, + fields, + } + } + #[track_caller] + fn get_fields< + B: ValueType, + C: ValueType, + >( + fields: &mut Vec>, + path_prefix: &mut Vec>, + bundle: B, + get_field: impl Copy + Fn(&B, Interned) -> C, + interface_from_bundle: impl Copy + Fn(B) -> T, + bundle_from_canonical: impl Copy + Fn(C) -> B, + ) { + let bundle_fields = bundle.ty().fields(); + if bundle_fields.iter().any(|f| f.flipped) + && bundle_fields.iter().any(|f| *f.name == *"config") + { + let value = interface_from_bundle(bundle); + fields.push(MemoryInterfacesBundleField { + path: MemoryInterfacesBundleFieldPath::from_slice(path_prefix), + value, + }); + } else { + for f in &bundle_fields { + assert!( + !f.flipped, + "field must not have #[hdl(flip)]: {}", + MemoryInterfacesBundleFieldPath::from_slice(path_prefix), + ); + let field = get_field(&bundle, f.name); + match field.ty() { + CanonicalType::Bundle(_) => { + path_prefix.push(f.name); + Self::get_fields( + fields, + path_prefix, + bundle_from_canonical(field), + get_field, + interface_from_bundle, + bundle_from_canonical, + ); + path_prefix.pop(); + } + CanonicalType::PhantomConst(_) => continue, + _ => panic!( + "field type must be either a MemoryInterfacesBundle or a PhantomConst: {}", + MemoryInterfacesBundleFieldPath::from_slice(path_prefix), + ), + } + } + } + } +} + +/// `Self` is a bundle where either: +/// * `Self` is a [`MemoryInterface>`] +/// * each field is a [`MemoryInterfacesBundle`] or a [`PhantomConst`] and none of the fields have `#[hdl(flip)]` +pub trait MemoryInterfacesBundle: BundleType { + #[track_caller] + fn properties_valueless( + self, + mut path_prefix: Vec>, + ) -> MemoryInterfacesBundleProperties< + Valueless>>, + > { + let mut fields = Vec::new(); + MemoryInterfacesBundleProperties::get_fields( + &mut fields, + &mut path_prefix, + Valueless::new(Bundle::new(self.fields())), + |&bundle, name| { + Valueless::new( + bundle + .ty() + .field_by_name(name) + .expect("field is known to exist") + .ty, + ) + }, + |bundle| Valueless::new(MemoryInterface::from_canonical(bundle.ty().canonical())), + |canonical| Valueless::new(Bundle::from_canonical(canonical.ty())), + ); + MemoryInterfacesBundleProperties::from_fields(fields) + } + #[track_caller] + fn properties_expr( + this: impl ToExpr, + mut path_prefix: Vec>, + ) -> MemoryInterfacesBundleProperties>>> + { + let mut fields = Vec::new(); + MemoryInterfacesBundleProperties::get_fields( + &mut fields, + &mut path_prefix, + Expr::as_bundle(this.to_expr()), + |&bundle, name| Expr::field(bundle, &name), + Expr::from_bundle, + Expr::from_canonical, + ); + MemoryInterfacesBundleProperties::from_fields(fields) + } +} + +impl MemoryInterfacesBundle for Bundle {} + +/// get the input's [`MemoryInterfaceConfig`] for [`memory_interface_resize_adapter_no_split()`] +pub fn memory_interface_resize_adapter_no_split_input_config( + output_config: PhantomConst, + input_log2_bus_width_in_bytes: u8, +) -> PhantomConst { + let MemoryInterfaceConfig { + log2_bus_width_in_bytes: _, + queue_capacity, + op_id_width, + address_range, + } = *output_config.get(); + PhantomConst::new_sized(MemoryInterfaceConfig { + log2_bus_width_in_bytes: input_log2_bus_width_in_bytes, + queue_capacity, + op_id_width, + address_range, + }) +} + +#[hdl] +fn get_shrink_no_split_output_start( + input_start: Expr>>, + output_config: PhantomConst, +) -> Expr>>> { + #[hdl] + let MemoryOperationStart::<_> { + kind, + addr, + write_data, + rw_mask, + op_id, + config: _, + } = input_start; + let input_config = input_start.ty().config; + let output_bus_width_in_bytes = output_config.get().bus_width_in_bytes(); + let input_bus_width_in_bytes = input_config.get().bus_width_in_bytes(); + assert_eq!(input_bus_width_in_bytes % output_bus_width_in_bytes, 0); + + #[hdl(no_static)] + struct OutputStartData> { + addr: UInt<64>, + write_data: ArrayType, MemoryInterfaceBusWidthInBytes>, + rw_mask: ArrayType>, + config: C, + } + + #[hdl(no_static)] + struct ReduceState { + at_least_one: Bool, + more_than_one: Bool, + output_start_data: T, + } + + let output_start_data_ty = OutputStartData[output_config]; + let reduce_state_ty = ReduceState[output_start_data_ty]; + + let Some((reduce_state, _)) = prefix_sum::reduce( + rw_mask + .chunks(output_bus_width_in_bytes) + .enumerate() + .map(|(index, rw_mask_chunk)| { + let reduce_state = wire_with_loc( + &format!("reduce_state_{index}"), + SourceLocation::caller(), + reduce_state_ty, + ); + connect( + reduce_state.at_least_one, + rw_mask_chunk.cast_to_bits().any_one_bits(), + ); + connect(reduce_state.more_than_one, false); + connect( + reduce_state.output_start_data, + UInt[output_start_data_ty.canonical().bit_width()] + .zero() + .cast_bits_to(output_start_data_ty), + ); + #[hdl] + if reduce_state.at_least_one { + #[hdl] + let OutputStartData::<_> { + addr: output_addr, + write_data: output_write_data, + rw_mask: output_rw_mask, + config: _, + } = reduce_state.output_start_data; + let start_byte = index * output_bus_width_in_bytes; + let byte_range = start_byte..start_byte + output_bus_width_in_bytes; + connect_any(output_addr, addr | start_byte); + for ((i, output_write_data), output_rw_mask) in + byte_range.zip(output_write_data).zip(output_rw_mask) + { + connect(output_write_data, write_data[i]); + connect(output_rw_mask, rw_mask[i]); + } + } + (reduce_state, format!("{index}")) + }), + |(l, l_str), (r, r_str)| -> (Expr>, String) { + let out_str = l_str + "_" + &*r_str; + let reduce_state = wire_with_loc( + &format!("reduce_state_{out_str}"), + SourceLocation::caller(), + reduce_state_ty, + ); + connect( + reduce_state, + #[hdl] + ReduceState::<_> { + at_least_one: l.at_least_one | r.at_least_one, + more_than_one: l.more_than_one + | r.more_than_one + | (l.at_least_one & r.at_least_one), + output_start_data: (l.output_start_data.cast_to_bits() + | r.output_start_data.cast_to_bits()) + .cast_bits_to(output_start_data_ty), + }, + ); + (reduce_state, out_str) + }, + ) else { + unreachable!("known to be non-empty"); + }; + #[hdl] + let ReduceState::<_> { + at_least_one, + more_than_one, + output_start_data, + } = reduce_state; + + #[hdl] + let shrink_no_split_output_start = wire(HdlOption[MemoryOperationStart[output_config]]); + + #[hdl] + if more_than_one { + connect( + shrink_no_split_output_start, + shrink_no_split_output_start.ty().HdlNone(), + ); + } else { + #[hdl] + let OutputStartData::<_> { + addr: output_start_data_addr, + write_data, + rw_mask, + config: _, + } = output_start_data; + #[hdl] + let output_addr = wire(); + #[hdl] + if at_least_one { + connect(output_addr, output_start_data_addr); + } else { + connect(output_addr, addr); + } + connect( + shrink_no_split_output_start, + HdlSome( + #[hdl] + MemoryOperationStart::<_> { + kind, + addr: output_addr, + write_data, + rw_mask, + op_id, + config: output_config, + }, + ), + ); + } + + shrink_no_split_output_start +} + +/// Adaptor to a memory interface with a smaller bus width. +/// Operations return errors if they would need to be split into more than one operation on the output. +#[hdl_module] +fn memory_interface_shrink_adapter_no_split( + output_config: PhantomConst, + input_log2_bus_width_in_bytes: u8, +) { + let queue_capacity = output_config.get().queue_capacity; + let output_bus_width_in_bytes = output_config.get().bus_width_in_bytes(); + let input_config = memory_interface_resize_adapter_no_split_input_config( + output_config, + input_log2_bus_width_in_bytes, + ); + let input_bus_width_in_bytes = input_config.get().bus_width_in_bytes(); + assert_eq!(input_bus_width_in_bytes % output_bus_width_in_bytes, 0); + + #[hdl] + let cd: ClockDomain = m.input(); + #[hdl] + let input_interface: MemoryInterface> = + m.input(MemoryInterface[input_config]); + #[hdl] + let output_interface: MemoryInterface> = + m.output(MemoryInterface[output_config]); + + connect(input_interface.next_op_ids, output_interface.next_op_ids); + + #[hdl] + struct QueueEntry { + is_error: Bool, + } + + #[hdl] + let queue = instance(queue(QueueEntry, queue_capacity, false, false)); + + connect(queue.cd, cd); + + #[hdl] + if !queue.inp.ready { + connect(input_interface.start.ready, false); + connect( + output_interface.start.data, + output_interface.ty().start.data.HdlNone(), + ); + connect(queue.inp.data, queue.ty().inp.data.HdlNone()); + } else { + connect(input_interface.start.ready, output_interface.start.ready); + #[hdl] + if let HdlSome(input_start) = input_interface.start.data { + let output_start = get_shrink_no_split_output_start(input_start, output_config); + connect(output_interface.start.data, output_start); + #[hdl] + if let HdlSome(_) = output_start { + #[hdl] + if input_interface.start.ready { + connect( + queue.inp.data, + HdlSome( + #[hdl] + QueueEntry { is_error: false }, + ), + ); + } else { + connect(queue.inp.data, HdlNone()); + } + } else { + connect( + queue.inp.data, + HdlSome( + #[hdl] + QueueEntry { is_error: true }, + ), + ); + } + } else { + connect( + output_interface.start.data, + output_interface.ty().start.data.HdlNone(), + ); + connect(queue.inp.data, queue.ty().inp.data.HdlNone()); + } + } + + connect(queue.out.ready, input_interface.finish.ready); + + #[hdl] + if let HdlSome(queue_out) = queue.out.data { + #[hdl] + let QueueEntry { is_error } = queue_out; + #[hdl] + if is_error { + connect( + input_interface.finish.data, + HdlSome( + #[hdl] + MemoryOperationFinish::<_> { + kind: MemoryOperationFinishKind.Error(MemoryOperationErrorKind.Generic()), + read_data: repeat(0u8, input_bus_width_in_bytes), + config: input_config, + }, + ), + ); + connect(output_interface.finish.ready, false); + } else { + connect(output_interface.finish.ready, input_interface.finish.ready); + #[hdl] + if let HdlSome(output_finish) = output_interface.finish.data { + #[hdl] + let MemoryOperationFinish::<_> { + kind, + read_data, + config: _, + } = output_finish; + #[hdl] + let input_finish = wire(input_interface.ty().finish.data.HdlSome); + connect(input_finish.config, input_finish.ty().config); + connect(input_finish.kind, kind); + for (l, r) in input_finish + .read_data + .into_iter() + .zip(read_data.into_iter().cycle()) + { + connect(l, r); + } + connect(input_interface.finish.data, HdlSome(input_finish)); + } else { + connect( + input_interface.finish.data, + input_interface.ty().finish.data.HdlNone(), + ); + } + } + } else { + connect(output_interface.finish.ready, false); + connect( + input_interface.finish.data, + input_interface.ty().finish.data.HdlNone(), + ); + } +} + +/// Adaptor to a memory interface with a different bus width. +/// Operations return errors if they would need to be split into more than one operation on the output. +#[hdl_module] +pub fn memory_interface_resize_adapter_no_split( + output_config: PhantomConst, + input_log2_bus_width_in_bytes: u8, +) { + let input_config = memory_interface_resize_adapter_no_split_input_config( + output_config, + input_log2_bus_width_in_bytes, + ); + #[hdl] + let cd: ClockDomain = m.input(); + #[hdl] + let input_interface: MemoryInterface> = + m.input(MemoryInterface[input_config]); + #[hdl] + let output_interface: MemoryInterface> = + m.output(MemoryInterface[output_config]); + match output_config + .get() + .log2_bus_width_in_bytes + .cmp(&input_log2_bus_width_in_bytes) + { + Ordering::Less => { + #[hdl] + let shrink_adapter = instance(memory_interface_shrink_adapter_no_split( + output_config, + input_log2_bus_width_in_bytes, + )); + connect(shrink_adapter.cd, cd); + connect(shrink_adapter.input_interface, input_interface); + connect(output_interface, shrink_adapter.output_interface); + } + Ordering::Equal => { + connect(output_interface, input_interface); + return; + } + Ordering::Greater => todo!( + "connecting a input memory interface to a output memory interface with larger bus width" + ), + } +} + +/// Adapt an input [`MemoryInterface`] to a collection of output [`MemoryInterface`]s (see [`MemoryInterfacesBundle`] for how that works). +/// The output interface used for each operation is the first output interface that matches [`MemoryInterfaceConfig::address_range`]. +/// If none match, then the operation returns an error. +/// Operations return errors if they would need to be split into more than one operation on the output. +#[hdl_module] +pub fn memory_interface_adapter_no_split( + input_config: PhantomConst, + output_interfaces_ty: OutputInterfaces, +) { + #[hdl] + let cd: ClockDomain = m.input(); + #[hdl] + let input_interface: MemoryInterface> = + m.input(MemoryInterface[input_config]); + #[hdl] + let output_interfaces: OutputInterfaces = m.output(output_interfaces_ty); + let mut output_interfaces = MemoryInterfacesBundle::properties_expr( + output_interfaces, + vec!["output_interfaces".intern()], + ); + if let Some(index) = output_interfaces.first_full_interface() { + assert!( + index == output_interfaces.fields().len() - 1, + "all fields after {path} will never be used since {path} comes before and handles all addresses", + path = output_interfaces.fields[index].path, + ); + } else { + #[hdl] + let always_error = instance(memory_interface_always_error(PhantomConst::new_sized( + memory_interface_always_error_config(*input_config.get()), + ))); + let mut fields = output_interfaces.into_fields(); + fields.push(MemoryInterfacesBundleField { + path: MemoryInterfacesBundleFieldPath::from_slice(&[ + "always_error".intern(), + "input_interface".intern(), + ]), + value: always_error.input_interface, + }); + output_interfaces = MemoryInterfacesBundleProperties::from_fields(fields); + } + + for field in output_interfaces.fields() { + let MemoryInterfaceConfig { + log2_bus_width_in_bytes: _, + queue_capacity: _, + op_id_width: _, + address_range, + } = *field.value.ty().config.get(); + let start = address_range.start().0; + let size_or_zero = address_range.size().map_or(0, |v| v.get()); + let input_bus_width_in_bytes = input_config.get().bus_width_in_bytes() as u64; + assert!( + start.is_multiple_of(input_bus_width_in_bytes) + && size_or_zero.is_multiple_of(input_bus_width_in_bytes), + "output interface's address_range must start and end on a multiple of the input interface's bus width in bytes:\n\ + {}: address_range={address_range:?} input_bus_width_in_bytes={input_bus_width_in_bytes:#x} ({input_bus_width_in_bytes})", + field.path, + ); + } + + output_interfaces = MemoryInterfacesBundleProperties::from_fields( + output_interfaces + .into_fields() + .into_iter() + .map(|MemoryInterfacesBundleField { path, value }| { + let output_config = value.ty().config; + let MemoryInterfaceConfig { + log2_bus_width_in_bytes: _, + queue_capacity, + op_id_width: _, + address_range, + } = *output_config.get(); + let MemoryInterfaceConfig { + log2_bus_width_in_bytes: input_log2_bus_width_in_bytes, + queue_capacity: _, + op_id_width, + address_range: _, + } = *input_config.get(); + let expected_config = MemoryInterfaceConfig { + log2_bus_width_in_bytes: input_log2_bus_width_in_bytes, + queue_capacity, + op_id_width, + address_range, + }; + if expected_config == *output_config.get() { + return MemoryInterfacesBundleField { path, value }; + } + let resize_adapter = instance_with_loc( + &format!("resize_adapter_{path}") + .replace(|ch: char| !ch.is_ascii_alphanumeric(), "_"), + memory_interface_resize_adapter_no_split( + output_config, + input_log2_bus_width_in_bytes, + ), + SourceLocation::caller(), + ); + connect(resize_adapter.cd, cd); + connect(value, resize_adapter.output_interface); + assert_eq!(value.ty(), MemoryInterface[value.ty().config]); + let value = resize_adapter.input_interface; + assert_eq!( + expected_config, + *value.ty().config.get(), + "can't adapt output interface: {path}", + ); + assert_eq!(value.ty(), MemoryInterface[value.ty().config]); + MemoryInterfacesBundleField { + path, + value: resize_adapter.input_interface, + } + }) + .collect(), + ); + + dbg!(std::fmt::from_fn(|f| f + .debug_map() + .entries( + output_interfaces + .fields() + .iter() + .map(|field| (field.path, field.value.ty())) + ) + .finish())); + + fn visit_selected_output_interface( + output_interfaces: &MemoryInterfacesBundleProperties< + Expr>>, + >, + selected_output_interface: impl ToExpr, DynSize>>, + mut visit_selected: impl FnMut( + usize, + MemoryInterfacesBundleField>>>, + ), + ) { + let selected_output_interface = selected_output_interface.to_expr(); + let mut else_scope = None; + for (i, &interface) in output_interfaces.fields().iter().enumerate() { + if i == output_interfaces.fields().len() - 1 { + // just else, no else if + visit_selected(i, interface); + } else { + let if_scope = fayalite::module::if_(selected_output_interface.cmp_eq(i)); + visit_selected(i, interface); + else_scope = Some(if_scope.else_()); + } + } + drop(else_scope); + } + + connect( + input_interface.next_op_ids, + input_interface.ty().next_op_ids.HdlNone(), + ); + + #[hdl(no_static)] + struct Op { + output_interface_index: UIntInRangeType, OutputInterfaceCount>, + } + + #[hdl(no_static)] + struct StartOp, OutputInterfaceCount: Size> { + start: MemoryOperationStart, + op: Op, + } + + let start_op_ty = StartOp[input_config][output_interfaces.fields().len()]; + let op_ty = Op[output_interfaces.fields().len()]; + + #[hdl] + let not_started_op_queue = instance(queue( + start_op_ty, + const { NonZeroUsize::new(1).unwrap() }, + false, + true, + )); + + connect(not_started_op_queue.cd, cd); + assert_eq!( + output_interfaces.first_full_interface(), + Some(output_interfaces.fields().len() - 1), + "guaranteed by above code adding memory_interface_always_error if necessary", + ); + connect( + not_started_op_queue.inp.data, + HdlOption::map(input_interface.start.data, |start| { + #[hdl] + let output_interface_index = wire(op_ty.output_interface_index); + // iterate in reverse order so last-connect semantics give us the + // first output interface that matches. + // output_interface_index is guaranteed to be written because we know the last + // output interface has AddressRange::Full + for (index, output_interface) in output_interfaces.fields().iter().enumerate().rev() { + match output_interface.value.ty().config.get().address_range { + AddressRange::Full => connect( + output_interface_index, + index.cast_to(output_interface_index.ty()), + ), + AddressRange::Limited { + start: address_range_start, + size, + } => { + let from_start: Expr> = + (start.addr - address_range_start.0).cast_to_static(); + #[hdl] + if from_start.cmp_lt(size) { + connect( + output_interface_index, + index.cast_to(output_interface_index.ty()), + ); + } + } + } + connect( + output_interface_index, + index.cast_to(output_interface_index.ty()), + ); + } + #[hdl] + StartOp::<_, _> { + start, + op: #[hdl] + Op::<_> { + output_interface_index, + }, + } + }), + ); + connect(input_interface.start.ready, not_started_op_queue.inp.ready); + + #[hdl] + let op_queue = instance(queue( + op_ty, + input_config.get().queue_capacity, + false, + false, + )); + connect(op_queue.cd, cd); + connect(op_queue.inp.data, op_queue.ty().inp.data.HdlNone()); + + connect(not_started_op_queue.out.ready, false); + for output_interface in output_interfaces.fields() { + connect( + output_interface.value.start.data, + output_interface.value.ty().start.data.HdlNone(), + ); + connect(output_interface.value.finish.ready, false); + } + + #[hdl] + if let HdlSome(start_op) = not_started_op_queue.out.data { + #[hdl] + let StartOp::<_, _> { start, op } = start_op; + #[hdl] + let Op::<_> { + output_interface_index, + } = op; + #[hdl] + let MemoryOperationStart::<_> { + kind, + addr, + write_data, + rw_mask, + op_id, + config: _, + } = start; + visit_selected_output_interface( + &output_interfaces, + output_interface_index, + |_, output_interface| { + connect( + output_interface.value.start.data, + HdlSome( + #[hdl] + MemoryOperationStart::<_> { + kind, + addr, + write_data, + rw_mask, + op_id, + config: output_interface.value.ty().config, + }, + ), + ); + #[hdl] + if output_interface.value.start.ready & op_queue.inp.ready { + connect(not_started_op_queue.out.ready, true); + connect(op_queue.inp.data, HdlSome(op)); + } + }, + ); + } + + connect(op_queue.out.ready, false); + connect( + input_interface.finish.data, + input_interface.ty().finish.data.HdlNone(), + ); + + #[hdl] + if let HdlSome(op) = op_queue.out.data { + #[hdl] + let Op::<_> { + output_interface_index, + } = op; + visit_selected_output_interface( + &output_interfaces, + output_interface_index, + |_, output_interface| { + connect( + output_interface.value.finish.ready, + input_interface.finish.ready, + ); + #[hdl] + if let HdlSome(finish) = output_interface.value.finish.data { + #[hdl] + let MemoryOperationFinish::<_> { + kind, + read_data, + config: _, + } = finish; + connect( + input_interface.finish.data, + HdlSome( + #[hdl] + MemoryOperationFinish::<_> { + kind, + read_data, + config: input_config, + }, + ), + ); + connect(op_queue.out.ready, input_interface.finish.ready); + } + }, + ); + } +} diff --git a/crates/cpu/src/main_memory_and_io/simple_uart.rs b/crates/cpu/src/main_memory_and_io/simple_uart.rs index 7ed24a0..7a11ae9 100644 --- a/crates/cpu/src/main_memory_and_io/simple_uart.rs +++ b/crates/cpu/src/main_memory_and_io/simple_uart.rs @@ -358,9 +358,9 @@ pub fn receiver(queue_capacity: NonZeroUsize) { pub const SIMPLE_UART_RECEIVE_OFFSET: u64 = 0; pub const SIMPLE_UART_TRANSMIT_OFFSET: u64 = 0; pub const SIMPLE_UART_STATUS_OFFSET: u64 = 1; -pub const SIMPLE_UART_SIZE: NonZeroU64 = - NonZeroU64::new(1 << SIMPLE_UART_LOG2_SIZE).expect("known to be non-zero"); -pub const SIMPLE_UART_LOG2_SIZE: u8 = 1; +pub const SIMPLE_UART_LOG2_BUS_WIDTH: u8 = 1; +pub const SIMPLE_UART_USED_SIZE: NonZeroU64 = NonZeroU64::new(2).expect("known non-zero"); +pub const SIMPLE_UART_ADDRESS_SIZE: NonZeroU64 = NonZeroU64::new(1 << 6).expect("known non-zero"); #[hdl(no_static)] struct Operation> { @@ -373,16 +373,18 @@ pub const fn simple_uart_memory_interface_config( start_address: Wrapping, ) -> MemoryInterfaceConfig { assert!( - start_address.0 % SIMPLE_UART_SIZE.get() == 0, + start_address + .0 + .is_multiple_of(SIMPLE_UART_ADDRESS_SIZE.get()), "start_address must be properly aligned" ); MemoryInterfaceConfig { - log2_bus_width_in_bytes: SIMPLE_UART_LOG2_SIZE, + log2_bus_width_in_bytes: SIMPLE_UART_LOG2_BUS_WIDTH, queue_capacity: const { NonZeroUsize::new(1).unwrap() }, op_id_width, address_range: AddressRange::Limited { start: start_address, - size: SIMPLE_UART_SIZE, + size: SIMPLE_UART_ADDRESS_SIZE, }, } } diff --git a/crates/cpu/tests/expected/memory_interface_adapter_no_split.vcd b/crates/cpu/tests/expected/memory_interface_adapter_no_split.vcd new file mode 100644 index 0000000..4d51a35 --- /dev/null +++ b/crates/cpu/tests/expected/memory_interface_adapter_no_split.vcd @@ -0,0 +1,7184 @@ +$timescale 1 ps $end +$scope module memory_interface_adapter_no_split_dut $end +$scope struct cd $end +$var wire 1 7Z.$. clk $end +$var wire 1 }MTh| rst $end +$upscope $end +$var wire 1 `[F_& finished $end +$scope struct mock_cpu $end +$scope struct cd $end +$var wire 1 3v&1D clk $end +$var wire 1 .IY;M rst $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 ^eu`/ \$tag $end +$scope struct HdlSome $end +$var string 1 9+$)l kind $end +$var wire 64 q9o58 addr $end +$scope struct write_data $end +$var wire 8 ,#Cd8 \[0] $end +$var wire 8 A.(rW \[1] $end +$var wire 8 $/iO^ \[2] $end +$var wire 8 HxC#4 \[3] $end +$var wire 8 Z\3Jf \[4] $end +$var wire 8 z4\7+ \[5] $end +$var wire 8 cryw} \[6] $end +$var wire 8 +h{& \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 ~!OEs \[0] $end +$var wire 1 <(=T9 \[1] $end +$var wire 1 2Sv(# \[2] $end +$var wire 1 T?]_] \[3] $end +$var wire 1 p:BL' \[4] $end +$var wire 1 M7pzK \[5] $end +$var wire 1 #Ye<} \[6] $end +$var wire 1 XKqh( \[7] $end +$upscope $end +$var wire 8 s"W}- op_id $end +$var string 1 jcM+1 config $end +$upscope $end +$upscope $end +$var wire 1 }LwcT ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 &"_S5 \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 ATlSR \$tag $end +$var string 1 1,9!q Success $end +$var string 1 3!]!A Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 lqb+8 \[0] $end +$var wire 8 c>]Gc \[1] $end +$var wire 8 }ut3 \[5] $end +$var wire 8 ]|sA1 \[6] $end +$var wire 8 &kIA: \[7] $end +$upscope $end +$var string 1 +_t|~ config $end +$upscope $end +$upscope $end +$var wire 1 9b,d\ ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 ^<]#< \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 JLP8n \[0] $end +$var wire 8 p|{U* \[1] $end +$var wire 8 LZc0u \[2] $end +$var wire 8 VO"xA \[3] $end +$var wire 8 >DNt= \[4] $end +$var wire 8 Lo5LX \[5] $end +$var wire 8 *'3(u \[6] $end +$var wire 8 R.66B \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 {Y|/9 value $end +$var string 1 8al|H range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 ':\&1 config $end +$upscope $end +$var wire 1 p8MPu finished $end +$upscope $end +$scope module mock_cpu_2 $end +$scope struct cd $end +$var wire 1 3v&1D" clk $end +$var wire 1 .IY;M" rst $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 ^eu`/" \$tag $end +$scope struct HdlSome $end +$var string 1 9+$)l" kind $end +$var wire 64 q9o58" addr $end +$scope struct write_data $end +$var wire 8 ,#Cd8" \[0] $end +$var wire 8 A.(rW" \[1] $end +$var wire 8 $/iO^" \[2] $end +$var wire 8 HxC#4" \[3] $end +$var wire 8 Z\3Jf" \[4] $end +$var wire 8 z4\7+" \[5] $end +$var wire 8 cryw}" \[6] $end +$var wire 8 +h{&!" \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 ~!OEs" \[0] $end +$var wire 1 <(=T9" \[1] $end +$var wire 1 2Sv(#" \[2] $end +$var wire 1 T?]_]" \[3] $end +$var wire 1 p:BL'" \[4] $end +$var wire 1 M7pzK" \[5] $end +$var wire 1 #Ye<}" \[6] $end +$var wire 1 XKqh(" \[7] $end +$upscope $end +$var wire 8 s"W}-" op_id $end +$var string 1 jcM+1" config $end +$upscope $end +$upscope $end +$var wire 1 }LwcT" ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 &"_S5" \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 ATlSR" \$tag $end +$var string 1 1,9!q" Success $end +$var string 1 3!]!A" Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 lqb+8" \[0] $end +$var wire 8 c>]Gc" \[1] $end +$var wire 8 }ut3" \[5] $end +$var wire 8 ]|sA1" \[6] $end +$var wire 8 &kIA:" \[7] $end +$upscope $end +$var string 1 +_t|~" config $end +$upscope $end +$upscope $end +$var wire 1 9b,d\" ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 ^<]#<" \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 JLP8n" \[0] $end +$var wire 8 p|{U*" \[1] $end +$var wire 8 LZc0u" \[2] $end +$var wire 8 VO"xA" \[3] $end +$var wire 8 >DNt=" \[4] $end +$var wire 8 Lo5LX" \[5] $end +$var wire 8 *'3(u" \[6] $end +$var wire 8 R.66B" \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 {Y|/9" value $end +$var string 1 8al|H" range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 ':\&1" config $end +$upscope $end +$var wire 1 p8MPu" finished $end +$upscope $end +$scope struct mock_mem_0 $end +$scope struct cd $end +$var wire 1 t,f{i clk $end +$var wire 1 t[3h= rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 zK+hs \$tag $end +$scope struct HdlSome $end +$var string 1 ;a1oK kind $end +$var wire 64 0F=tx addr $end +$scope struct write_data $end +$var wire 8 {xMN^ \[0] $end +$var wire 8 WxxRb \[1] $end +$var wire 8 1fQwT \[2] $end +$var wire 8 (cPn< \[3] $end +$var wire 8 iyxp* \[4] $end +$var wire 8 %_@@\ \[5] $end +$var wire 8 KkrZ0 \[6] $end +$var wire 8 {w.Gl \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 `L:Kx \[0] $end +$var wire 1 c@wv- \[1] $end +$var wire 1 r".cQ \[2] $end +$var wire 1 1i=j% \[3] $end +$var wire 1 Iw)Lr \[4] $end +$var wire 1 u1"m- \[5] $end +$var wire 1 3Ri/, \[6] $end +$var wire 1 KTxgS \[7] $end +$upscope $end +$var wire 8 I5xTL op_id $end +$var string 1 .k|Cd config $end +$upscope $end +$upscope $end +$var wire 1 {Dr|8 ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 p.*bZ \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 OO)vV value $end +$var string 1 >fI,] range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 ),;@& config $end +$upscope $end +$upscope $end +$scope module mock_memory $end +$scope struct cd $end +$var wire 1 b}F_+ clk $end +$var wire 1 ]2Q-p rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 ?F#c7 \$tag $end +$scope struct HdlSome $end +$var string 1 \}F6u kind $end +$var wire 64 'iKg* addr $end +$scope struct write_data $end +$var wire 8 -xW.o \[0] $end +$var wire 8 `q)a; \[1] $end +$var wire 8 L[)VS \[2] $end +$var wire 8 b`Lq/ \[3] $end +$var wire 8 Ix,K| \[4] $end +$var wire 8 _l,eF \[5] $end +$var wire 8 MU1WG \[6] $end +$var wire 8 83qZN \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 \qI>7 \[0] $end +$var wire 1 V_5A^ \[1] $end +$var wire 1 AS \[7] $end +$upscope $end +$var string 1 EjI7P config $end +$upscope $end +$upscope $end +$var wire 1 .SOQ/ ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 Od;kq \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 8ibWx \[0] $end +$var wire 8 0WfOZ \[1] $end +$var wire 8 %cc2p \[2] $end +$var wire 8 (Q>[: \[3] $end +$var wire 8 \+}M3 \[4] $end +$var wire 8 ?OGzQ \[5] $end +$var wire 8 aqLzM \[6] $end +$var wire 8 3CAi3 \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 0=E8% value $end +$var string 1 +C1); range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 ?/2G; config $end +$upscope $end +$upscope $end +$scope struct mock_mem_1 $end +$scope struct cd $end +$var wire 1 ,kkUh clk $end +$var wire 1 9Jb6Z rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 WO#p_ \$tag $end +$scope struct HdlSome $end +$var string 1 $1PO` kind $end +$var wire 64 J1KKs addr $end +$scope struct write_data $end +$var wire 8 Ds>&L \[0] $end +$var wire 8 77dMD \[1] $end +$var wire 8 yO(@8 \[2] $end +$var wire 8 0bGFr \[3] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 L;+3| \[0] $end +$var wire 1 Yd1ON \[1] $end +$var wire 1 .UDju \[2] $end +$var wire 1 !7,p} \[3] $end +$upscope $end +$var wire 8 jaYR0 op_id $end +$var string 1 =61"3 config $end +$upscope $end +$upscope $end +$var wire 1 "T*hK ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 3KIn: \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 VR4CL \$tag $end +$var string 1 3)>:& Success $end +$var string 1 $,>1@ Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 <-bA% \[0] $end +$var wire 8 8+TL\ \[1] $end +$var wire 8 ,tE\/ \[2] $end +$var wire 8 BroV9 \[3] $end +$upscope $end +$var string 1 }/q3t config $end +$upscope $end +$upscope $end +$var wire 1 Q-7" \[0] $end +$var wire 1 V_5A^" \[1] $end +$var wire 1 A[:" \[3] $end +$var wire 8 \+}M3" \[4] $end +$var wire 8 ?OGzQ" \[5] $end +$var wire 8 aqLzM" \[6] $end +$var wire 8 3CAi3" \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 0=E8%" value $end +$var string 1 +C1);" range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 ?/2G;" config $end +$upscope $end +$upscope $end +$scope struct mock_mem_2 $end +$scope struct cd $end +$var wire 1 U\\gA clk $end +$var wire 1 k@&rZ rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 ,.H8y \$tag $end +$scope struct HdlSome $end +$var string 1 +-n=$ kind $end +$var wire 64 fY[|> addr $end +$scope struct write_data $end +$var wire 8 3MsTg \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 @IO:] \[0] $end +$upscope $end +$var wire 8 54*\X op_id $end +$var string 1 pvOZ\ config $end +$upscope $end +$upscope $end +$var wire 1 5=*5a ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 Q\Vx5 \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 uauH, \$tag $end +$var string 1 z3`!* Success $end +$var string 1 %UEdc Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 \""s; \[0] $end +$upscope $end +$var string 1 (3p)0 config $end +$upscope $end +$upscope $end +$var wire 1 hiVl: ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 Pm+T_ \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 boa7W \[0] $end +$var wire 8 ZG{VR \[1] $end +$var wire 8 3\"?o \[2] $end +$var wire 8 r7o^J \[3] $end +$var wire 8 cJorP \[4] $end +$var wire 8 ?p7~ \[5] $end +$var wire 8 !{\us \[6] $end +$var wire 8 d7Jx? \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 \Ayk, value $end +$var string 1 ;X[b; range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 L#_3] config $end +$upscope $end +$upscope $end +$scope module mock_memory_3 $end +$scope struct cd $end +$var wire 1 b}F_+# clk $end +$var wire 1 ]2Q-p# rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 ?F#c7# \$tag $end +$scope struct HdlSome $end +$var string 1 \}F6u# kind $end +$var wire 64 'iKg*# addr $end +$scope struct write_data $end +$var wire 8 -xW.o# \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 \qI>7# \[0] $end +$upscope $end +$var wire 8 f*.L1# op_id $end +$var string 1 TOPPc# config $end +$upscope $end +$upscope $end +$var wire 1 9Kr<,# ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 q#KNc# \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 K4!SI# \$tag $end +$var string 1 ,@dh\# Success $end +$var string 1 .pVac# Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 zhnfr# \[0] $end +$upscope $end +$var string 1 EjI7P# config $end +$upscope $end +$upscope $end +$var wire 1 .SOQ/# ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 Od;kq# \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 8ibWx# \[0] $end +$var wire 8 0WfOZ# \[1] $end +$var wire 8 %cc2p# \[2] $end +$var wire 8 (Q>[:# \[3] $end +$var wire 8 \+}M3# \[4] $end +$var wire 8 ?OGzQ# \[5] $end +$var wire 8 aqLzM# \[6] $end +$var wire 8 3CAi3# \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 0=E8%# value $end +$var string 1 +C1);# range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 ?/2G;# config $end +$upscope $end +$upscope $end +$scope struct adapter $end +$scope struct cd $end +$var wire 1 W?Hp~ clk $end +$var wire 1 _]m=\ rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 wjjEV \$tag $end +$scope struct HdlSome $end +$var string 1 mglkY kind $end +$var wire 64 1y!RS addr $end +$scope struct write_data $end +$var wire 8 yf$TD \[0] $end +$var wire 8 _kDIS \[1] $end +$var wire 8 C(77z \[2] $end +$var wire 8 vy{V< \[3] $end +$var wire 8 79H@q \[4] $end +$var wire 8 7yPfs \[5] $end +$var wire 8 \"@Q7 \[6] $end +$var wire 8 |bsUw \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 Mv+$0 \[0] $end +$var wire 1 W/x9+ \[1] $end +$var wire 1 m)\5f \[2] $end +$var wire 1 Qo^bw \[3] $end +$var wire 1 /t.wP \[4] $end +$var wire 1 g?u_Y \[5] $end +$var wire 1 USD_s \[6] $end +$var wire 1 [KPI* \[7] $end +$upscope $end +$var wire 8 {T7hv op_id $end +$var string 1 N`B*t config $end +$upscope $end +$upscope $end +$var wire 1 1;JQ^ ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 e.~]E \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 "M,X; \$tag $end +$var string 1 !DxRJ Success $end +$var string 1 \ZSl] Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 c5W@* \[0] $end +$var wire 8 ?4QjV \[1] $end +$var wire 8 ;|Aqn \[2] $end +$var wire 8 f448; \[3] $end +$var wire 8 SX+N\ \[4] $end +$var wire 8 ci0zj \[5] $end +$var wire 8 Utm?q \[6] $end +$var wire 8 1?.bq \[7] $end +$upscope $end +$var string 1 ANd]< config $end +$upscope $end +$upscope $end +$var wire 1 9C+iW ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 4wB3; \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 G%Xf" \[0] $end +$var wire 8 ^hV1y \[1] $end +$var wire 8 A_Mcu \[2] $end +$var wire 8 M8Jbj \[3] $end +$var wire 8 OyJzS \[4] $end +$var wire 8 .PiLo \[5] $end +$var wire 8 F(}+6 \[6] $end +$var wire 8 n_V=D \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 jpsY) value $end +$var string 1 1#HFy range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 :MjuY config $end +$upscope $end +$scope struct output_interfaces $end +$scope struct \0 $end +$scope struct start $end +$scope struct data $end +$var string 1 np$oq \$tag $end +$scope struct HdlSome $end +$var string 1 +F8oo kind $end +$var wire 64 c5fPr addr $end +$scope struct write_data $end +$var wire 8 oz/?< \[0] $end +$var wire 8 -^N!& \[1] $end +$var wire 8 j.CJz \[2] $end +$var wire 8 xZ6w$ \[3] $end +$var wire 8 I!IyC \[4] $end +$var wire 8 !~yml \[5] $end +$var wire 8 ;%1YG \[6] $end +$var wire 8 #u^v[ \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 xw3*n \[0] $end +$var wire 1 3MmE- \[1] $end +$var wire 1 J6"p\ \[2] $end +$var wire 1 4y0A> \[3] $end +$var wire 1 "=3`U \[4] $end +$var wire 1 |/[bs \[5] $end +$var wire 1 ITlw\ \[6] $end +$var wire 1 Xmq~1 \[7] $end +$upscope $end +$var wire 8 =dq8M op_id $end +$var string 1 jZuCk config $end +$upscope $end +$upscope $end +$var wire 1 >6&v2 ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 'SG%{ \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 ?l*T; \$tag $end +$var string 1 ZWG)3 Success $end +$var string 1 EDNkm Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 r[Pix \[0] $end +$var wire 8 Xq(iG \[1] $end +$var wire 8 gUg1| \[2] $end +$var wire 8 )4f{a \[3] $end +$var wire 8 >7g3p \[4] $end +$var wire 8 B(b7B \[5] $end +$var wire 8 r{D0O \[6] $end +$var wire 8 [/Z>s \[7] $end +$upscope $end +$var string 1 ceQp% config $end +$upscope $end +$upscope $end +$var wire 1 JewCi ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 ]lv__ \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 qciRv \[0] $end +$var wire 8 &i=E< \[1] $end +$var wire 8 -B)\; \[2] $end +$var wire 8 4REHN \[3] $end +$var wire 8 |o1m% \[4] $end +$var wire 8 6cwGg \[5] $end +$var wire 8 nSY:X \[6] $end +$var wire 8 Ve94A \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 )+f{_ value $end +$var string 1 r)?`J range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 Y8V6| config $end +$upscope $end +$scope struct \1 $end +$scope struct start $end +$scope struct data $end +$var string 1 BiRsb \$tag $end +$scope struct HdlSome $end +$var string 1 lpY:~ kind $end +$var wire 64 Olcb@ addr $end +$scope struct write_data $end +$var wire 8 B*Yy4 \[0] $end +$var wire 8 ~A_TB \[1] $end +$var wire 8 FoK"Z \[2] $end +$var wire 8 1k]ct \[3] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 h@V4t \[0] $end +$var wire 1 :"U|2 \[1] $end +$var wire 1 =(^$` \[2] $end +$var wire 1 ^LobZ \[3] $end +$upscope $end +$var wire 8 U`oQ* op_id $end +$var string 1 8?PW` config $end +$upscope $end +$upscope $end +$var wire 1 4|.Py ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 JGh2) \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 x4q}C \$tag $end +$var string 1 C\_/W Success $end +$var string 1 rt!2l Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 T:gt\ \[0] $end +$var wire 8 RlG5V \[1] $end +$var wire 8 ZdsQG \[2] $end +$var wire 8 #S~+R \[3] $end +$upscope $end +$var string 1 0/SmU config $end +$upscope $end +$upscope $end +$var wire 1 &'Zc6 ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 eS-=. \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 |Uk!E \[0] $end +$var wire 8 q>.SI \[1] $end +$var wire 8 Z~CdF \[2] $end +$var wire 8 @piu' \[3] $end +$var wire 8 ,`j;j \[4] $end +$var wire 8 Wg4 \[2] $end +$var wire 8 "DgJu \[3] $end +$var wire 8 DS7S_ \[4] $end +$var wire 8 W,){k \[5] $end +$var wire 8 dD'oW \[6] $end +$var wire 8 pScRY \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 [x"|) \[0] $end +$var wire 1 1FIL0 \[1] $end +$var wire 1 _A%V) \[2] $end +$var wire 1 &{[W= \[3] $end +$var wire 1 p,1bO \[4] $end +$var wire 1 h}+.T \[5] $end +$var wire 1 {h'l/ \[6] $end +$var wire 1 },v-@ \[7] $end +$upscope $end +$var wire 8 _InNh op_id $end +$var string 1 Wp{|r config $end +$upscope $end +$upscope $end +$var wire 1 :1PrP ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 ]j'7p \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 ~9Ybc \$tag $end +$var string 1 ^VVDP Success $end +$var string 1 :"uUm Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 [}N3Q \[0] $end +$var wire 8 I>.mI \[1] $end +$var wire 8 G9!-h \[2] $end +$var wire 8 }7Yat \[3] $end +$var wire 8 8vHY5 \[4] $end +$var wire 8 *&^)r \[5] $end +$var wire 8 9*/}O \[6] $end +$var wire 8 )/um( \[7] $end +$upscope $end +$var string 1 ``,U^ config $end +$upscope $end +$upscope $end +$var wire 1 k^6"m ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 02F~C \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 DLgd) \[0] $end +$var wire 8 Yn;La \[1] $end +$var wire 8 +IxDk \[2] $end +$var wire 8 N*L(q \[3] $end +$var wire 8 l^L1 \$tag $end +$var string 1 0DeSA Success $end +$var string 1 p\\h/ Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 n]!VA \[0] $end +$var wire 8 mc ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 !_]?y \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 jUOE( \$tag $end +$var string 1 ]-|~o Success $end +$var string 1 ;YG^& Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 -uY[w \[0] $end +$var wire 8 n"C.- \[1] $end +$var wire 8 -8tqe \[2] $end +$var wire 8 am*w, \[3] $end +$upscope $end +$var string 1 2J!)$ config $end +$upscope $end +$upscope $end +$var wire 1 +\+Pz ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 = range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 282'p config $end +$upscope $end +$scope struct \2 $end +$scope struct start $end +$scope struct data $end +$var string 1 BSCn4 \$tag $end +$scope struct HdlSome $end +$var string 1 yd5Dy kind $end +$var wire 64 5O4DG addr $end +$scope struct write_data $end +$var wire 8 d!lLQ \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 Um#Oh \[0] $end +$upscope $end +$var wire 8 ?z]{L op_id $end +$var string 1 +1=;I config $end +$upscope $end +$upscope $end +$var wire 1 po3;M ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 fM;PI \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 .yxFW \$tag $end +$var string 1 :OTk> Success $end +$var string 1 mhn}0 Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 hgWbG \[0] $end +$upscope $end +$var string 1 ;DibH config $end +$upscope $end +$upscope $end +$var wire 1 dt}g9 ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 ;5dr1 \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 qWe2t \[0] $end +$var wire 8 HweTb \[1] $end +$var wire 8 2HXbL \[2] $end +$var wire 8 a8LX) \[3] $end +$var wire 8 w9uB: \[4] $end +$var wire 8 p\|p< \[5] $end +$var wire 8 L!mah \[6] $end +$var wire 8 tfo(b \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 0xQ=% value $end +$var string 1 {]-7b range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 _+{*U config $end +$upscope $end +$upscope $end +$scope struct and_then_out $end +$var string 1 ]MN.k \$tag $end +$scope struct HdlSome $end +$scope struct start $end +$var string 1 sM,ig kind $end +$var wire 64 =Fu[V addr $end +$scope struct write_data $end +$var wire 8 kv*+i \[0] $end +$var wire 8 jTB}~ \[1] $end +$var wire 8 5Dst$ \[2] $end +$var wire 8 [7tEQ \[3] $end +$var wire 8 .SWIf \[4] $end +$var wire 8 ?Me0A \[5] $end +$var wire 8 Fi_z" \[6] $end +$var wire 8 L6#}x \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 &0Noi \[0] $end +$var wire 1 GcKtT \[1] $end +$var wire 1 C7R|D \[2] $end +$var wire 1 c'v6Y \[3] $end +$var wire 1 L2o7} \[4] $end +$var wire 1 Z6\#x \[5] $end +$var wire 1 "'OCX \[6] $end +$var wire 1 13lt| \[7] $end +$upscope $end +$var wire 8 HszjQ op_id $end +$var string 1 MQ&&} config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 OZ2^Q value $end +$var string 1 09#6W range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$scope struct always_error $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 h+dr+ \$tag $end +$scope struct HdlSome $end +$var string 1 j!~Ew kind $end +$var wire 64 AV64s addr $end +$scope struct write_data $end +$var wire 8 Y|}pJ \[0] $end +$var wire 8 $5K config $end +$upscope $end +$upscope $end +$var wire 1 z~~:S \[6] $end +$var wire 8 qSBc6 \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 7d+[x \[0] $end +$var wire 1 Xnk'W \[1] $end +$var wire 1 .C[8' \[2] $end +$var wire 1 L`]e0 \[3] $end +$var wire 1 /*xwY \[4] $end +$var wire 1 XN:$" \[5] $end +$var wire 1 f&U6 \[5] $end +$var wire 8 HD[R" \[6] $end +$var wire 8 =V9Jq \[7] $end +$upscope $end +$var string 1 (B]kQ config $end +$upscope $end +$upscope $end +$var wire 1 t[}s6 ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 hP{gt \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 z:+(@ \[0] $end +$upscope $end +$scope struct len $end +$var wire 1 iEDB3h clk $end +$var wire 1 >>\@Q rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 p#h%k \$tag $end +$scope struct HdlSome $end +$var string 1 4OS6x kind $end +$var wire 64 wZ#~{ addr $end +$scope struct write_data $end +$var wire 8 owJuR \[0] $end +$var wire 8 Cj>06 \[1] $end +$var wire 8 Bllp/ \[2] $end +$var wire 8 Q}gw? \[3] $end +$var wire 8 r+qf> \[4] $end +$var wire 8 NHEO? \[5] $end +$var wire 8 ;+k/C \[6] $end +$var wire 8 *D^^" \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 %OVG~ \[0] $end +$var wire 1 P215H \[1] $end +$var wire 1 9.vvP \[2] $end +$var wire 1 -}sQa \[3] $end +$var wire 1 Zbf'q \[4] $end +$var wire 1 os5&Y \[5] $end +$var wire 1 )lYu@ \[6] $end +$var wire 1 (dA6b \[7] $end +$upscope $end +$var wire 8 `^n[, op_id $end +$var string 1 z*"5J config $end +$upscope $end +$upscope $end +$var wire 1 iR$H[ ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 X!c#K \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 1QvrF \$tag $end +$var string 1 jUA{4 Success $end +$var string 1 [3\kk Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 bO~O' \[0] $end +$var wire 8 D##_H \[1] $end +$var wire 8 VNr(c \[2] $end +$var wire 8 r+q"E \[3] $end +$var wire 8 DMTaz \[4] $end +$var wire 8 zkhtj \[5] $end +$var wire 8 uc'5" \[6] $end +$var wire 8 #6}y{ \[7] $end +$upscope $end +$var string 1 }7kxz config $end +$upscope $end +$upscope $end +$var wire 1 yEvWo ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 {S{+O \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 v>{58 \[0] $end +$var wire 8 To[FQ \[1] $end +$var wire 8 `/4zP \[2] $end +$var wire 8 [KEF: \[3] $end +$var wire 8 \:f[C \[4] $end +$var wire 8 *Q{Y# \[5] $end +$var wire 8 e"`qK \[6] $end +$var wire 8 Zz-H= \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 h;1CX value $end +$var string 1 _$]kF range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 t<)Eb config $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 WaG') \$tag $end +$scope struct HdlSome $end +$var string 1 Yx+[Q kind $end +$var wire 64 KT$)+ addr $end +$scope struct write_data $end +$var wire 8 fQk.t \[3] $end +$var wire 8 z\-#- \[4] $end +$var wire 8 Z=O^| \[5] $end +$var wire 8 `>e]R \[6] $end +$var wire 8 'B|ac \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 7?oLf \[0] $end +$var wire 1 ~8qof \[1] $end +$var wire 1 SAr3k \[2] $end +$var wire 1 $l9b^ \[3] $end +$var wire 1 2uYp& \[4] $end +$var wire 1 ,36/r \[5] $end +$var wire 1 A?lPe \[6] $end +$var wire 1 T>3j| \[7] $end +$upscope $end +$var wire 8 )Z68v op_id $end +$var string 1 dBm[y config $end +$upscope $end +$upscope $end +$var wire 1 uFc0' ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 U4@L' \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 k[b|4 \$tag $end +$var string 1 )%?'V Success $end +$var string 1 Z0f\j Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 MZ{gf \[0] $end +$var wire 8 4fJ+*i \[6] $end +$var wire 8 e<~Eb \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 "|?fC value $end +$var string 1 9ZYIC range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 jO{Dq config $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 5&97& \$tag $end +$scope struct HdlSome $end +$var string 1 8:%R9 kind $end +$var wire 64 Sr98H addr $end +$scope struct write_data $end +$var wire 8 #fTp; \[0] $end +$var wire 8 ]&V$] \[1] $end +$var wire 8 I,dhN \[2] $end +$var wire 8 `7~"5 \[3] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 $e>rg \[0] $end +$var wire 1 )Z0Fs \[1] $end +$var wire 1 H];UQ \[2] $end +$var wire 1 .m6,b \[3] $end +$upscope $end +$var wire 8 "Q^x_ op_id $end +$var string 1 aE%(j config $end +$upscope $end +$upscope $end +$var wire 1 9"'Jr ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 n:-3L \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 v3h>^ \$tag $end +$var string 1 2Y_0v Success $end +$var string 1 4j02? Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 $VB%, \[0] $end +$var wire 8 zydP\ \[1] $end +$var wire 8 ]l{;7 \[2] $end +$var wire 8 4n~n8 \[3] $end +$upscope $end +$var string 1 N_C[d config $end +$upscope $end +$upscope $end +$var wire 1 H:0@M ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 |6zh: \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 Nnv*n \[5] $end +$var wire 8 ]s1rd \[6] $end +$var wire 8 xS@qB \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 f3iRp \[0] $end +$var wire 1 $yjZ, \[1] $end +$var wire 1 zmzdN \[2] $end +$var wire 1 ,f`F+ \[3] $end +$var wire 1 LK"UV \[4] $end +$var wire 1 bc2~. \[5] $end +$var wire 1 7_Bvx \[6] $end +$var wire 1 3\"Nj \[7] $end +$upscope $end +$var wire 8 {*%0k op_id $end +$var string 1 ~{8K0 config $end +$upscope $end +$upscope $end +$var wire 1 c>U|% ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 }JY0H \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 ^udcB \$tag $end +$var string 1 f?~C8 Success $end +$var string 1 ='~t/ Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 LF4%[ \[0] $end +$var wire 8 ?hS@| \[1] $end +$var wire 8 Z ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 m(9Y, \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 |k range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 7q$j3 config $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 @Z \$tag $end +$scope struct HdlSome $end +$var string 1 qzT.O kind $end +$var wire 64 +W<2 addr $end +$scope struct write_data $end +$var wire 8 }[w5S \[0] $end +$var wire 8 @eTQ| \[1] $end +$var wire 8 WNNgC \[2] $end +$var wire 8 Ej|;& \[3] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 Bp_CT \[0] $end +$var wire 1 ^u,ix \[1] $end +$var wire 1 G+>7W \[2] $end +$var wire 1 .=AZ* \[3] $end +$upscope $end +$var wire 8 2pyaqg \$tag $end +$var string 1 ", \[0] $end +$var wire 1 eI<6i \[1] $end +$var wire 1 Lc>f/ \[2] $end +$var wire 1 ~#X87 \[3] $end +$var wire 1 MuvtB \[4] $end +$var wire 1 i3rnI \[5] $end +$var wire 1 I'q_? \[6] $end +$var wire 1 )t{[U \[7] $end +$upscope $end +$var wire 8 |bTLs op_id $end +$var string 1 w&S5S config $end +$upscope $end +$upscope $end +$var wire 1 r9Nnr ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 ]Ej[\ \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 {*ZH. \$tag $end +$var string 1 0WC)D Success $end +$var string 1 Fi>dZ Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 98zvW \[0] $end +$var wire 8 *x=!b \[1] $end +$var wire 8 ;-Wz} \[2] $end +$var wire 8 9'-5 addr $end +$scope struct write_data $end +$var wire 8 le/]y \[0] $end +$var wire 8 AA3J3 \[1] $end +$var wire 8 4x/E{ \[2] $end +$var wire 8 ! \[4] $end +$var wire 8 cb-10 \[5] $end +$var wire 8 mn{ik \[6] $end +$var wire 8 Uz[0U \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 AZ!Wg value $end +$var string 1 ^=A2D range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 (0rdC config $end +$upscope $end +$scope struct queue $end +$scope struct cd $end +$var wire 1 'ohSl clk $end +$var wire 1 q[z5A rst $end +$upscope $end +$scope struct inp $end +$scope struct data $end +$var string 1 O>A\0 \$tag $end +$scope struct HdlSome $end +$var wire 1 XA\0" \$tag $end +$scope struct HdlSome $end +$var wire 1 Xvg firing $end +$var wire 1 jM}qk out_firing $end +$var wire 1 Uf>vg" firing_2 $end +$var wire 1 |GaPb indexes_equal $end +$var wire 1 >hk?I empty $end +$var wire 1 3To8{ full $end +$scope struct unwrap_or_else_out $end +$var wire 1 cy_"a is_error $end +$upscope $end +$var wire 3 )6skj count_lower $end +$upscope $end +$scope struct reduce_state_0 $end +$var wire 1 x[Lr| at_least_one $end +$var wire 1 6TG~t more_than_one $end +$scope struct output_start_data $end +$var wire 64 hk;4D addr $end +$scope struct write_data $end +$var wire 8 1c_gk \[0] $end +$var wire 8 }$5+* \[1] $end +$var wire 8 k=H^A \[2] $end +$var wire 8 y!=UJ \[3] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 6T$6- \[0] $end +$var wire 1 zE~_0 \[1] $end +$var wire 1 Pi.k9 \[2] $end +$var wire 1 o^]QN \[3] $end +$upscope $end +$var string 1 1WgGS config $end +$upscope $end +$upscope $end +$scope struct reduce_state_1 $end +$var wire 1 ptpr+ at_least_one $end +$var wire 1 L0d{N more_than_one $end +$scope struct output_start_data $end +$var wire 64 Heja: addr $end +$scope struct write_data $end +$var wire 8 \:@B8 \[0] $end +$var wire 8 ww:- \[3] $end +$upscope $end +$var string 1 {NH:- config $end +$upscope $end +$upscope $end +$scope struct shrink_no_split_output_start $end +$var string 1 4Z4x8 \$tag $end +$scope struct HdlSome $end +$var string 1 iTh$> kind $end +$var wire 64 EaRqh addr $end +$scope struct write_data $end +$var wire 8 $Uo]g \[0] $end +$var wire 8 BS*a> \[1] $end +$var wire 8 jZ)fY \[2] $end +$var wire 8 [[(kn \[3] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 t.lS# \[0] $end +$var wire 1 zr4o9 \[1] $end +$var wire 1 H3A]g \[2] $end +$var wire 1 oJYjk \[3] $end +$upscope $end +$var wire 8 8&p?/ op_id $end +$var string 1 _[f9R config $end +$upscope $end +$upscope $end +$var wire 64 m{*__ output_addr $end +$scope struct input_finish $end +$scope struct kind $end +$var string 1 l[fye \$tag $end +$var string 1 k:{2w Success $end +$var string 1 V)Q)? Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 [.>| \[0] $end +$var wire 8 EYP&Z \[1] $end +$var wire 8 7zb]V \[2] $end +$var wire 8 vhAS^ \[3] $end +$var wire 8 S0PWH \[4] $end +$var wire 8 &\y)U \[5] $end +$var wire 8 ]]u/b \[6] $end +$var wire 8 8"[Uj \[7] $end +$upscope $end +$var string 1 3j_%Y config $end +$upscope $end +$upscope $end +$upscope $end +$scope struct resize_adapter_output_interfaces_2 $end +$scope struct cd $end +$var wire 1 ly!Za clk $end +$var wire 1 }K4m; rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 9s{nl \$tag $end +$scope struct HdlSome $end +$var string 1 yUOvm kind $end +$var wire 64 lx_a+ addr $end +$scope struct write_data $end +$var wire 8 Fjmgp \[0] $end +$var wire 8 *"XE3 \[1] $end +$var wire 8 ^:T/> \[2] $end +$var wire 8 8o]vK \[3] $end +$var wire 8 T5k5x \[4] $end +$var wire 8 UW~DU \[5] $end +$var wire 8 &X^|* \[6] $end +$var wire 8 0wJ^} \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 3`\nb \[0] $end +$var wire 1 l{$kj \[1] $end +$var wire 1 ;S^U| \[2] $end +$var wire 1 VfyoK \[3] $end +$var wire 1 DvX6A \[4] $end +$var wire 1 I2dd_ \[5] $end +$var wire 1 V(%D. \[6] $end +$var wire 1 _uXDb \[7] $end +$upscope $end +$var wire 8 'z$t< op_id $end +$var string 1 NtLP9 config $end +$upscope $end +$upscope $end +$var wire 1 IQt>v ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 VmI%y \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 IKB)% \$tag $end +$var string 1 +|FzD Success $end +$var string 1 fas): Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 mg"r] \[0] $end +$var wire 8 h!s^i \[1] $end +$var wire 8 D'gKs \[2] $end +$var wire 8 %zV12 \[3] $end +$var wire 8 2buNY \[4] $end +$var wire 8 B>OKu \[5] $end +$var wire 8 &'-QM \[6] $end +$var wire 8 ?+F%y \[7] $end +$upscope $end +$var string 1 zqOzP config $end +$upscope $end +$upscope $end +$var wire 1 ;H~?) ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 fv6%d \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 ({53A \[0] $end +$var wire 8 FK[+c \[1] $end +$var wire 8 2Z6r~ \[2] $end +$var wire 8 '$`LB \[3] $end +$var wire 8 MpmDr \[4] $end +$var wire 8 qXb)4 \[5] $end +$var wire 8 3+mZM \[6] $end +$var wire 8 =.UVZ \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 ,iC/t value $end +$var string 1 uX9~O range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 C[e/B config $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 W/\W+ \$tag $end +$scope struct HdlSome $end +$var string 1 X= \[2] $end +$var wire 8 T9vmz \[3] $end +$var wire 8 ;a+`< \[4] $end +$var wire 8 &{pV0 \[5] $end +$var wire 8 MLaH6 \[6] $end +$var wire 8 C\d2; \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 A!''D value $end +$var string 1 sjj!t range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 7EHvW config $end +$upscope $end +$upscope $end +$scope module memory_interface_resize_adapter_no_split_2 $end +$scope struct cd $end +$var wire 1 [Qu?z" clk $end +$var wire 1 PK0LO" rst $end +$upscope $end +$scope struct input_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 ?oh=}" \$tag $end +$scope struct HdlSome $end +$var string 1 9ntWw" kind $end +$var wire 64 ds/w@" addr $end +$scope struct write_data $end +$var wire 8 mT{Zw" \[0] $end +$var wire 8 x$"Wf" \[1] $end +$var wire 8 m&d^?" \[2] $end +$var wire 8 >Qk.t" \[3] $end +$var wire 8 z\-#-" \[4] $end +$var wire 8 Z=O^|" \[5] $end +$var wire 8 `>e]R" \[6] $end +$var wire 8 'B|ac" \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 7?oLf" \[0] $end +$var wire 1 ~8qof" \[1] $end +$var wire 1 SAr3k" \[2] $end +$var wire 1 $l9b^" \[3] $end +$var wire 1 2uYp&" \[4] $end +$var wire 1 ,36/r" \[5] $end +$var wire 1 A?lPe" \[6] $end +$var wire 1 T>3j|" \[7] $end +$upscope $end +$var wire 8 )Z68v" op_id $end +$var string 1 dBm[y" config $end +$upscope $end +$upscope $end +$var wire 1 uFc0'" ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 U4@L'" \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 k[b|4" \$tag $end +$var string 1 )%?'V" Success $end +$var string 1 Z0f\j" Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 MZ{gf" \[0] $end +$var wire 8 4fJ+*i" \[6] $end +$var wire 8 e<~Eb" \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 "|?fC" value $end +$var string 1 9ZYIC" range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 jO{Dq" config $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 5&97&" \$tag $end +$scope struct HdlSome $end +$var string 1 8:%R9" kind $end +$var wire 64 Sr98H" addr $end +$scope struct write_data $end +$var wire 8 #fTp;" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 $e>rg" \[0] $end +$upscope $end +$var wire 8 "Q^x_" op_id $end +$var string 1 aE%(j" config $end +$upscope $end +$upscope $end +$var wire 1 9"'Jr" ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 n:-3L" \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 v3h>^" \$tag $end +$var string 1 2Y_0v" Success $end +$var string 1 4j02?" Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 $VB%," \[0] $end +$upscope $end +$var string 1 N_C[d" config $end +$upscope $end +$upscope $end +$var wire 1 H:0@M" ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 |6zh:" \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 Nnv*n" \[5] $end +$var wire 8 ]s1rd" \[6] $end +$var wire 8 xS@qB" \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 f3iRp" \[0] $end +$var wire 1 $yjZ," \[1] $end +$var wire 1 zmzdN" \[2] $end +$var wire 1 ,f`F+" \[3] $end +$var wire 1 LK"UV" \[4] $end +$var wire 1 bc2~." \[5] $end +$var wire 1 7_Bvx" \[6] $end +$var wire 1 3\"Nj" \[7] $end +$upscope $end +$var wire 8 {*%0k" op_id $end +$var string 1 ~{8K0" config $end +$upscope $end +$upscope $end +$var wire 1 c>U|%" ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 }JY0H" \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 ^udcB" \$tag $end +$var string 1 f?~C8" Success $end +$var string 1 ='~t/" Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 LF4%[" \[0] $end +$var wire 8 ?hS@|" \[1] $end +$var wire 8 Z" ready $end +$upscope $end +$scope struct next_op_ids $end +$var string 1 m(9Y," \$tag $end +$scope struct HdlSome $end +$scope struct elements $end +$var wire 8 |k" range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 7q$j3" config $end +$upscope $end +$scope struct output_interface $end +$scope struct start $end +$scope struct data $end +$var string 1 @Z" \$tag $end +$scope struct HdlSome $end +$var string 1 qzT.O" kind $end +$var wire 64 +W<2!" addr $end +$scope struct write_data $end +$var wire 8 }[w5S" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 Bp_CT" \[0] $end +$upscope $end +$var wire 8 2pyaqg" \$tag $end +$var string 1 "," \[0] $end +$var wire 1 eI<6i" \[1] $end +$var wire 1 Lc>f/" \[2] $end +$var wire 1 ~#X87" \[3] $end +$var wire 1 MuvtB" \[4] $end +$var wire 1 i3rnI" \[5] $end +$var wire 1 I'q_?" \[6] $end +$var wire 1 )t{[U" \[7] $end +$upscope $end +$var wire 8 |bTLs" op_id $end +$var string 1 w&S5S" config $end +$upscope $end +$upscope $end +$var wire 1 r9Nnr" ready $end +$upscope $end +$scope struct finish $end +$scope struct data $end +$var string 1 ]Ej[\" \$tag $end +$scope struct HdlSome $end +$scope struct kind $end +$var string 1 {*ZH." \$tag $end +$var string 1 0WC)D" Success $end +$var string 1 Fi>dZ" Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 98zvW" \[0] $end +$var wire 8 *x=!b" \[1] $end +$var wire 8 ;-Wz}" \[2] $end +$var wire 8 9'-5" addr $end +$scope struct write_data $end +$var wire 8 le/]y" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 w'51o" \[0] $end +$upscope $end +$var wire 8 f" \[4] $end +$var wire 8 cb-10" \[5] $end +$var wire 8 mn{ik" \[6] $end +$var wire 8 Uz[0U" \[7] $end +$upscope $end +$scope struct len $end +$var wire 4 AZ!Wg" value $end +$var string 1 ^=A2D" range $end +$upscope $end +$upscope $end +$upscope $end +$var string 1 (0rdC" config $end +$upscope $end +$scope struct queue $end +$scope struct cd $end +$var wire 1 'ohSl# clk $end +$var wire 1 q[z5A# rst $end +$upscope $end +$scope struct inp $end +$scope struct data $end +$var string 1 O>A\0# \$tag $end +$scope struct HdlSome $end +$var wire 1 XA\0$ \$tag $end +$scope struct HdlSome $end +$var wire 1 Xvg# firing $end +$var wire 1 jM}qk" out_firing $end +$var wire 1 Uf>vg$ firing_2 $end +$var wire 1 |GaPb" indexes_equal $end +$var wire 1 >hk?I" empty $end +$var wire 1 3To8{" full $end +$scope struct unwrap_or_else_out $end +$var wire 1 cy_"a" is_error $end +$upscope $end +$var wire 3 )6skj" count_lower $end +$upscope $end +$scope struct reduce_state_0 $end +$var wire 1 x[Lr|" at_least_one $end +$var wire 1 6TG~t" more_than_one $end +$scope struct output_start_data $end +$var wire 64 hk;4D" addr $end +$scope struct write_data $end +$var wire 8 1c_gk" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 6T$6-" \[0] $end +$upscope $end +$var string 1 1WgGS" config $end +$upscope $end +$upscope $end +$scope struct reduce_state_1 $end +$var wire 1 ptpr+" at_least_one $end +$var wire 1 L0d{N" more_than_one $end +$scope struct output_start_data $end +$var wire 64 Heja:" addr $end +$scope struct write_data $end +$var wire 8 \:@B8" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 4t)VB" \[0] $end +$upscope $end +$var string 1 C\k5_" config $end +$upscope $end +$upscope $end +$scope struct reduce_state_2 $end +$var wire 1 ;4^pT at_least_one $end +$var wire 1 Uvu>/ more_than_one $end +$scope struct output_start_data $end +$var wire 64 ~0#Je addr $end +$scope struct write_data $end +$var wire 8 xkXiO \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 5gjp[ \[0] $end +$upscope $end +$var string 1 *S7*~ config $end +$upscope $end +$upscope $end +$scope struct reduce_state_3 $end +$var wire 1 S#TWr at_least_one $end +$var wire 1 T2q>B more_than_one $end +$scope struct output_start_data $end +$var wire 64 *B4E0 addr $end +$scope struct write_data $end +$var wire 8 3S7WO \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 tn at_least_one $end +$var wire 1 $[wv= more_than_one $end +$scope struct output_start_data $end +$var wire 64 "2_9l addr $end +$scope struct write_data $end +$var wire 8 @@)-G \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 pAnAd \[0] $end +$upscope $end +$var string 1 NdYm} config $end +$upscope $end +$upscope $end +$scope struct reduce_state_0_1 $end +$var wire 1 'H4D&" at_least_one $end +$var wire 1 -y1}:" more_than_one $end +$scope struct output_start_data $end +$var wire 64 Rzg.[" addr $end +$scope struct write_data $end +$var wire 8 yYt:L" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 /yppY" \[0] $end +$upscope $end +$var string 1 {NH:-" config $end +$upscope $end +$upscope $end +$scope struct reduce_state_4_5_6_7 $end +$var wire 1 4'qCV at_least_one $end +$var wire 1 PWYG* more_than_one $end +$scope struct output_start_data $end +$var wire 64 y)j'q addr $end +$scope struct write_data $end +$var wire 8 97u:z \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 6kJ@Y \[0] $end +$upscope $end +$var string 1 k*?v0 config $end +$upscope $end +$upscope $end +$scope struct reduce_state_0_1_2_3 $end +$var wire 1 8`]ji at_least_one $end +$var wire 1 YgAEs more_than_one $end +$scope struct output_start_data $end +$var wire 64 73$!^ addr $end +$scope struct write_data $end +$var wire 8 $5h$6 \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 hAq)G \[0] $end +$upscope $end +$var string 1 f%}S^ config $end +$upscope $end +$upscope $end +$scope struct reduce_state_0_1_2_3_4_5_6_7 $end +$var wire 1 i_"+u at_least_one $end +$var wire 1 f/^q3 more_than_one $end +$scope struct output_start_data $end +$var wire 64 #c2~e addr $end +$scope struct write_data $end +$var wire 8 ,g{ZD \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 MK\{x \[0] $end +$upscope $end +$var string 1 /{;*1 config $end +$upscope $end +$upscope $end +$scope struct shrink_no_split_output_start $end +$var string 1 4Z4x8" \$tag $end +$scope struct HdlSome $end +$var string 1 iTh$>" kind $end +$var wire 64 EaRqh" addr $end +$scope struct write_data $end +$var wire 8 $Uo]g" \[0] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 t.lS#" \[0] $end +$upscope $end +$var wire 8 8&p?/" op_id $end +$var string 1 _[f9R" config $end +$upscope $end +$upscope $end +$var wire 64 m{*__" output_addr $end +$scope struct input_finish $end +$scope struct kind $end +$var string 1 l[fye" \$tag $end +$var string 1 k:{2w" Success $end +$var string 1 V)Q)?" Error $end +$upscope $end +$scope struct read_data $end +$var wire 8 [.>|!" \[0] $end +$var wire 8 EYP&Z" \[1] $end +$var wire 8 7zb]V" \[2] $end +$var wire 8 vhAS^" \[3] $end +$var wire 8 S0PWH" \[4] $end +$var wire 8 &\y)U" \[5] $end +$var wire 8 ]]u/b" \[6] $end +$var wire 8 8"[Uj" \[7] $end +$upscope $end +$var string 1 3j_%Y" config $end +$upscope $end +$upscope $end +$upscope $end +$scope struct not_started_op_queue $end +$scope struct cd $end +$var wire 1 SEzxV clk $end +$var wire 1 M36~K rst $end +$upscope $end +$scope struct inp $end +$scope struct data $end +$var string 1 BMS_* \$tag $end +$scope struct HdlSome $end +$scope struct start $end +$var string 1 *{sP( kind $end +$var wire 64 _0e[y addr $end +$scope struct write_data $end +$var wire 8 4r8@a \[0] $end +$var wire 8 _`'$= \[1] $end +$var wire 8 Cz0|, \[2] $end +$var wire 8 D$X,j \[3] $end +$var wire 8 h]_9W \[4] $end +$var wire 8 mA`Sf \[5] $end +$var wire 8 N%X'~ \[6] $end +$var wire 8 !lQ[l \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 -_2Ng \[0] $end +$var wire 1 RZbuG \[1] $end +$var wire 1 %uw+, \[2] $end +$var wire 1 Q1HE< \[3] $end +$var wire 1 3LJN^ \[4] $end +$var wire 1 \8.Cs \[5] $end +$var wire 1 ZFqzE \[6] $end +$var wire 1 ?)"O@ \[7] $end +$upscope $end +$var wire 8 [>BA< op_id $end +$var string 1 f~RD$ config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 4z-H2 value $end +$var string 1 xOedc range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 `?E&S ready $end +$upscope $end +$scope struct out $end +$scope struct data $end +$var string 1 4{-zs \$tag $end +$scope struct HdlSome $end +$scope struct start $end +$var string 1 *TaVw kind $end +$var wire 64 ;tO$C addr $end +$scope struct write_data $end +$var wire 8 $XA}i \[0] $end +$var wire 8 F;oLB \[1] $end +$var wire 8 Q=j \[0] $end +$var wire 8 /n^.0 \[1] $end +$var wire 8 Gy|$z \[2] $end +$var wire 8 *-GzR \[3] $end +$var wire 8 dv}6` \[4] $end +$var wire 8 |MzD| \[5] $end +$var wire 8 +#4Ae \[6] $end +$var wire 8 7DG.0 \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 swSnp \[0] $end +$var wire 1 0!}9_ \[1] $end +$var wire 1 Eu[4Z \[2] $end +$var wire 1 v(pFI \[3] $end +$var wire 1 G(L]# \[4] $end +$var wire 1 a'Z"M \[5] $end +$var wire 1 woy8t \[6] $end +$var wire 1 O:-Ou \[7] $end +$upscope $end +$var wire 8 DlAX? op_id $end +$var string 1 3W|p* config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 [$u%~ value $end +$var string 1 kYdkn range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 5\}~> ready $end +$upscope $end +$scope struct out $end +$scope struct data $end +$var string 1 z[d;i \$tag $end +$scope struct HdlSome $end +$scope struct start $end +$var string 1 'vusN kind $end +$var wire 64 $>+uK addr $end +$scope struct write_data $end +$var wire 8 zCQ"e \[0] $end +$var wire 8 t8^C6 \[1] $end +$var wire 8 XX|nl \[2] $end +$var wire 8 8Y%Wk \[3] $end +$var wire 8 54RLx \[4] $end +$var wire 8 U"-'. \[5] $end +$var wire 8 =KKpu \[6] $end +$var wire 8 e$Wq| \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 }=#gh \[0] $end +$var wire 1 6f{rQ \[1] $end +$var wire 1 UlT#C \[2] $end +$var wire 1 ]XK,Q \[3] $end +$var wire 1 b4plV \[4] $end +$var wire 1 O0fXd \[5] $end +$var wire 1 #c].s \[6] $end +$var wire 1 3\e(. \[7] $end +$upscope $end +$var wire 8 vQk;& op_id $end +$var string 1 Zgh@V config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 ?`R@B value $end +$var string 1 0}{|# range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 t"bJH ready $end +$upscope $end +$var wire 1 .sMPc count $end +$scope struct mem $end +$scope struct contents $end +$scope struct \[0] $end +$scope struct mem $end +$scope struct start $end +$var string 1 19Kmc kind $end +$var reg 64 ?[)!| addr $end +$scope struct write_data $end +$var reg 8 Uc_7, \[0] $end +$var reg 8 !$$Ll \[1] $end +$var reg 8 KGgJT \[2] $end +$var reg 8 LV:Fm \[3] $end +$var reg 8 8%!L" \[4] $end +$var reg 8 ^Dz'& \[5] $end +$var reg 8 S2VYM \[6] $end +$var reg 8 dBB)0 \[7] $end +$upscope $end +$scope struct rw_mask $end +$var reg 1 ,W>.v \[0] $end +$var reg 1 iZU?z \[1] $end +$var reg 1 {}m6q \[2] $end +$var reg 1 Z1CM. \[3] $end +$var reg 1 Y;{RD \[4] $end +$var reg 1 #4eK< \[5] $end +$var reg 1 PBL"6 \[6] $end +$var reg 1 +9?iP \[7] $end +$upscope $end +$var reg 8 5}.LR op_id $end +$var string 1 I3yzX config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var reg 2 tOH2~ value $end +$var string 1 FQ en $end +$var wire 1 a:ro< clk $end +$scope struct data $end +$scope struct start $end +$var string 1 BQq`v kind $end +$var wire 64 X;(;e addr $end +$scope struct write_data $end +$var wire 8 bII(} \[0] $end +$var wire 8 IMrY` \[1] $end +$var wire 8 +XouE \[2] $end +$var wire 8 QZPbV \[3] $end +$var wire 8 =LM+p \[4] $end +$var wire 8 1|jHy \[5] $end +$var wire 8 A"hJ: \[6] $end +$var wire 8 ?b`Z} \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 ht@AC \[0] $end +$var wire 1 95qQh \[1] $end +$var wire 1 0)#7N \[2] $end +$var wire 1 o{5.4 \[3] $end +$var wire 1 m`EXj \[4] $end +$var wire 1 /=RNL \[5] $end +$var wire 1 XR14A \[6] $end +$var wire 1 -/RU< \[7] $end +$upscope $end +$var wire 8 8G`:M op_id $end +$var string 1 l|04C config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 139p] value $end +$var string 1 "dFO3 range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$scope struct w1 $end +$var string 0 Eec_# addr $end +$var wire 1 PLEF3 en $end +$var wire 1 .34:S clk $end +$scope struct data $end +$scope struct start $end +$var string 1 z@&Tn kind $end +$var wire 64 FkI@> addr $end +$scope struct write_data $end +$var wire 8 B4^}F \[0] $end +$var wire 8 `iD'f \[1] $end +$var wire 8 {_r@k \[2] $end +$var wire 8 Ps-7W \[3] $end +$var wire 8 2DzS} \[4] $end +$var wire 8 b*)<` \[5] $end +$var wire 8 C+?w; \[6] $end +$var wire 8 Qgp9] \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 xL}T[ \[0] $end +$var wire 1 P>7{t \[1] $end +$var wire 1 F?jn> \[2] $end +$var wire 1 s*%n' \[3] $end +$var wire 1 o$4A8 \[4] $end +$var wire 1 L32DC \[5] $end +$var wire 1 ZRo,\ \[6] $end +$var wire 1 EZt+2 \[7] $end +$upscope $end +$var wire 8 vEdKE op_id $end +$var string 1 \@u,: config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 Ha9z2 value $end +$var string 1 1ffCl range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct mask $end +$scope struct start $end +$var wire 1 Q,J^5 kind $end +$var wire 1 ffSyY addr $end +$scope struct write_data $end +$var wire 1 4dt=j \[0] $end +$var wire 1 )Cvf\ \[1] $end +$var wire 1 #x4t# \[2] $end +$var wire 1 9wSE" \[3] $end +$var wire 1 %zM|B \[4] $end +$var wire 1 ntM]@ \[5] $end +$var wire 1 %R1@3 \[6] $end +$var wire 1 eS,c@ \[7] $end +$upscope $end +$scope struct rw_mask $end +$var wire 1 vD^,9 \[0] $end +$var wire 1 bj$RP \[1] $end +$var wire 1 e155L \[2] $end +$var wire 1 m;aG\ \[3] $end +$var wire 1 dvGIO \[4] $end +$var wire 1 mX16b \[5] $end +$var wire 1 _+0bR \[6] $end +$var wire 1 A/-lz \[7] $end +$upscope $end +$var wire 1 E#PuA op_id $end +$scope struct config $end +$upscope $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 1 o]hNF value $end +$scope struct range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$var string 0 1201; inp_index_reg $end +$var string 0 z6UdP out_index_reg $end +$var reg 1 .T-}[ maybe_full_reg $end +$var wire 1 NG-f; inp_firing $end +$var wire 1 _eUF] firing $end +$var wire 1 [TO.D out_firing $end +$var wire 1 _eUF]" firing_2 $end +$var wire 1 4 \[1] $end +$var wire 1 0'"+n \[2] $end +$var wire 1 v+*l9 \[3] $end +$var wire 1 ^ \[6] $end +$var wire 1 O`-ue \[7] $end +$upscope $end +$var wire 8 Yi2hP op_id $end +$var string 1 j_laO config $end +$upscope $end +$scope struct op $end +$scope struct output_interface_index $end +$var wire 2 k-bFV value $end +$var string 1 1Sz{4 range $end +$upscope $end +$upscope $end +$upscope $end +$var string 0 0T17D count_lower $end +$upscope $end +$scope struct output_interface_index $end +$var wire 2 d>;=] value $end +$var string 1 :lV`' range $end +$upscope $end +$scope struct op_queue $end +$scope struct cd $end +$var wire 1 Q1S40 clk $end +$var wire 1 oj[@o rst $end +$upscope $end +$scope struct inp $end +$scope struct data $end +$var string 1 Kq>x2 \$tag $end +$scope struct HdlSome $end +$scope struct output_interface_index $end +$var wire 2 R\O,0 value $end +$var string 1 q}+|l range $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 zFkc^ ready $end +$upscope $end +$scope struct out $end +$scope struct data $end +$var string 1 \^:|R \$tag $end +$scope struct HdlSome $end +$scope struct output_interface_index $end +$var wire 2 X=:J. value $end +$var string 1 cNT/Y range $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 I2+~X ready $end +$upscope $end +$var wire 4 Ly1ZZ count $end +$upscope $end +$scope module queue_2 $end +$scope struct cd $end +$var wire 1 D)Up[" clk $end +$var wire 1 x~j-j" rst $end +$upscope $end +$scope struct inp $end +$scope struct data $end +$var string 1 D%xS," \$tag $end +$scope struct HdlSome $end +$scope struct output_interface_index $end +$var wire 2 Q&d`s value $end +$var string 1 J3qBr range $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 5\}~>" ready $end +$upscope $end +$scope struct out $end +$scope struct data $end +$var string 1 z[d;i" \$tag $end +$scope struct HdlSome $end +$scope struct output_interface_index $end +$var wire 2 YNu#3 value $end +$var string 1 z.*z9 range $end +$upscope $end +$upscope $end +$upscope $end +$var wire 1 t"bJH" ready $end +$upscope $end +$var wire 4 .sMPc" count $end +$scope struct mem $end +$scope struct contents $end +$scope struct \[0] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 P2'xQ value $end +$var string 1 NV\7B range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[1] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 iT&0^ value $end +$var string 1 QM[&" range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[2] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 98d`` value $end +$var string 1 DPg{' range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[3] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 Vy??D value $end +$var string 1 z~{P0 range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[4] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 =JfJW value $end +$var string 1 %#>#x range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[5] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 ?ma}L value $end +$var string 1 k^DBN range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[6] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 =#e*R value $end +$var string 1 j]r`3 range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct \[7] $end +$scope struct mem $end +$scope struct output_interface_index $end +$var reg 2 _P`)i value $end +$var string 1 ;X",r range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$scope struct r0 $end +$var wire 3 Fi)a"" addr $end +$var wire 1 t%>FQ" en $end +$var wire 1 a:ro<" clk $end +$scope struct data $end +$scope struct output_interface_index $end +$var wire 2 h4|FL value $end +$var string 1 2.h"; range $end +$upscope $end +$upscope $end +$upscope $end +$scope struct w1 $end +$var wire 3 Eec_#" addr $end +$var wire 1 PLEF3" en $end +$var wire 1 .34:S" clk $end +$scope struct data $end +$scope struct output_interface_index $end +$var wire 2 v&*FG value $end +$var string 1 [jY]& range $end +$upscope $end +$upscope $end +$scope struct mask $end +$scope struct output_interface_index $end +$var wire 1 kBn0e value $end +$scope struct range $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$var reg 3 1201;" inp_index_reg $end +$var reg 3 z6UdP" out_index_reg $end +$var reg 1 .T-}[" maybe_full_reg $end +$var wire 1 NG-f;" inp_firing $end +$var wire 1 _eUF]# firing $end +$var wire 1 [TO.D" out_firing $end +$var wire 1 _eUF]$ firing_2 $end +$var wire 1 .v +0iZU?z +0{}m6q +0Z1CM. +0Y;{RD +0#4eK< +0PBL"6 +0+9?iP +b0 5}.LR +s0 I3yzX +b0 tOH2~ +s0 #x +b0 ?ma}L +s0 k^DBN +b0 =#e*R +s0 j]r`3 +b0 _P`)i +s0 ;X",r +07Z.$. +1}MTh| +0`[F_& +03v&1D" +1.IY;M" +sHdlNone\x20(0) ^eu`/" +sRead\x20(0) 9+$)l" +b0 q9o58" +b0 ,#Cd8" +b0 A.(rW" +b0 $/iO^" +b0 HxC#4" +b0 Z\3Jf" +b0 z4\7+" +b0 cryw}" +b0 +h{&!" +0~!OEs" +0<(=T9" +02Sv(#" +0T?]_]" +0p:BL'" +0M7pzK" +0#Ye<}" +0XKqh(" +b0 s"W}-" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) jcM+1" +1}LwcT" +sHdlNone\x20(0) &"_S5" +sSuccess\x20(0) ATlSR" +sRead\x20(0) 1,9!q" +sGeneric\x20(0) 3!]!A" +b0 lqb+8" +b0 c>]Gc" +b0 }ut3" +b0 ]|sA1" +b0 &kIA:" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) +_t|~" +09b,d\" +sHdlNone\x20(0) ^<]#<" +b0 JLP8n" +b0 p|{U*" +b0 LZc0u" +b0 VO"xA" +b0 >DNt=" +b0 Lo5LX" +b0 *'3(u" +b0 R.66B" +b0 {Y|/9" +sPhantomConst(\"0..=8\") 8al|H" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) ':\&1" +0p8MPu" +03v&1D +1.IY;M +sHdlNone\x20(0) ^eu`/ +sRead\x20(0) 9+$)l +b0 q9o58 +b0 ,#Cd8 +b0 A.(rW +b0 $/iO^ +b0 HxC#4 +b0 Z\3Jf +b0 z4\7+ +b0 cryw} +b0 +h{& +0~!OEs +0<(=T9 +02Sv(# +0T?]_] +0p:BL' +0M7pzK +0#Ye<} +0XKqh( +b0 s"W}- +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) jcM+1 +1}LwcT +sHdlNone\x20(0) &"_S5 +sSuccess\x20(0) ATlSR +sRead\x20(0) 1,9!q +sGeneric\x20(0) 3!]!A +b0 lqb+8 +b0 c>]Gc +b0 }ut3 +b0 ]|sA1 +b0 &kIA: +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) +_t|~ +09b,d\ +sHdlNone\x20(0) ^<]#< +b0 JLP8n +b0 p|{U* +b0 LZc0u +b0 VO"xA +b0 >DNt= +b0 Lo5LX +b0 *'3(u +b0 R.66B +b0 {Y|/9 +sPhantomConst(\"0..=8\") 8al|H +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) ':\&1 +0p8MPu +0b}F_+ +1]2Q-p +sHdlNone\x20(0) ?F#c7 +sRead\x20(0) \}F6u +b0 'iKg* +b0 -xW.o +b0 `q)a; +b0 L[)VS +b0 b`Lq/ +b0 Ix,K| +b0 _l,eF +b0 MU1WG +b0 83qZN +0\qI>7 +0V_5A^ +0AS +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) EjI7P +0.SOQ/ +sHdlNone\x20(0) Od;kq +b0 8ibWx +b0 0WfOZ +b0 %cc2p +b0 (Q>[: +b0 \+}M3 +b0 ?OGzQ +b0 aqLzM +b0 3CAi3 +b0 0=E8% +sPhantomConst(\"0..=8\") +C1); +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) ?/2G; +0t,f{i +1t[3h= +sHdlNone\x20(0) zK+hs +sRead\x20(0) ;a1oK +b0 0F=tx +b0 {xMN^ +b0 WxxRb +b0 1fQwT +b0 (cPn< +b0 iyxp* +b0 %_@@\ +b0 KkrZ0 +b0 {w.Gl +0`L:Kx +0c@wv- +0r".cQ +01i=j% +0Iw)Lr +0u1"m- +03Ri/, +0KTxgS +b0 I5xTL +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) .k|Cd +0{Dr|8 +sHdlNone\x20(0) p.*bZ +sSuccess\x20(0) OO)vV +sPhantomConst(\"0..=8\") >fI,] +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) ),;@& +0b}F_+" +1]2Q-p" +sHdlNone\x20(0) ?F#c7" +sRead\x20(0) \}F6u" +b0 'iKg*" +b0 -xW.o" +b0 `q)a;" +b0 L[)VS" +b0 b`Lq/" +0\qI>7" +0V_5A^" +0A[:" +b0 \+}M3" +b0 ?OGzQ" +b0 aqLzM" +b0 3CAi3" +b0 0=E8%" +sPhantomConst(\"0..=8\") +C1);" +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) ?/2G;" +0,kkUh +19Jb6Z +sHdlNone\x20(0) WO#p_ +sRead\x20(0) $1PO` +b0 J1KKs +b0 Ds>&L +b0 77dMD +b0 yO(@8 +b0 0bGFr +0L;+3| +0Yd1ON +0.UDju +0!7,p} +b0 jaYR0 +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) =61"3 +0"T*hK +sHdlNone\x20(0) 3KIn: +sSuccess\x20(0) VR4CL +sRead\x20(0) 3)>:& +sGeneric\x20(0) $,>1@ +b0 <-bA% +b0 8+TL\ +b0 ,tE\/ +b0 BroV9 +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) }/q3t +0Q-7# +b0 f*.L1# +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) TOPPc# +09Kr<,# +sHdlNone\x20(0) q#KNc# +sSuccess\x20(0) K4!SI# +sRead\x20(0) ,@dh\# +sGeneric\x20(0) .pVac# +b0 zhnfr# +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) EjI7P# +0.SOQ/# +sHdlNone\x20(0) Od;kq# +b0 8ibWx# +b0 0WfOZ# +b0 %cc2p# +b0 (Q>[:# +b0 \+}M3# +b0 ?OGzQ# +b0 aqLzM# +b0 3CAi3# +b0 0=E8%# +sPhantomConst(\"0..=8\") +C1);# +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) ?/2G;# +0U\\gA +1k@&rZ +sHdlNone\x20(0) ,.H8y +sRead\x20(0) +-n=$ +b0 fY[|> +b0 3MsTg +0@IO:] +b0 54*\X +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) pvOZ\ +05=*5a +sHdlNone\x20(0) Q\Vx5 +sSuccess\x20(0) uauH, +sRead\x20(0) z3`!* +sGeneric\x20(0) %UEdc +b0 \""s; +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) (3p)0 +0hiVl: +sHdlNone\x20(0) Pm+T_ +b0 boa7W +b0 ZG{VR +b0 3\"?o +b0 r7o^J +b0 cJorP +b0 ?p7~ +b0 !{\us +b0 d7Jx? +b0 \Ayk, +sPhantomConst(\"0..=8\") ;X[b; +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) L#_3] +0b!RoJ +1XL7[o +sHdlNone\x20(0) H)GyP +sRead\x20(0) #*37z +b0 0]FS] +b0 G%?9c +b0 xd8"a +b0 LC4>4 +b0 "DgJu +b0 DS7S_ +b0 W,){k +b0 dD'oW +b0 pScRY +0[x"|) +01FIL0 +0_A%V) +0&{[W= +0p,1bO +0h}+.T +0{h'l/ +0},v-@ +b0 _InNh +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) Wp{|r +1:1PrP +sHdlNone\x20(0) ]j'7p +sSuccess\x20(0) ~9Ybc +sRead\x20(0) ^VVDP +sGeneric\x20(0) :"uUm +b0 [}N3Q +b0 I>.mI +b0 G9!-h +b0 }7Yat +b0 8vHY5 +b0 *&^)r +b0 9*/}O +b0 )/um( +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) ``,U^ +0k^6"m +sHdlNone\x20(0) 02F~C +b0 DLgd) +b0 Yn;La +b0 +IxDk +b0 N*L(q +b0 l^L1 +sRead\x20(0) 0DeSA +sGeneric\x20(0) p\\h/ +b0 n]!VA +b0 mc +sHdlNone\x20(0) !_]?y +sSuccess\x20(0) jUOE( +sRead\x20(0) ]-|~o +sGeneric\x20(0) ;YG^& +b0 -uY[w +b0 n"C.- +b0 -8tqe +b0 am*w, +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) 2J!)$ +0+\+Pz +sHdlNone\x20(0) = +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) 282'p +sHdlNone\x20(0) BSCn4 +sRead\x20(0) yd5Dy +b0 5O4DG +b0 d!lLQ +0Um#Oh +b0 ?z]{L +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) +1=;I +0po3;M +sHdlNone\x20(0) fM;PI +sSuccess\x20(0) .yxFW +sRead\x20(0) :OTk> +sGeneric\x20(0) mhn}0 +b0 hgWbG +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) ;DibH +0dt}g9 +sHdlNone\x20(0) ;5dr1 +b0 qWe2t +b0 HweTb +b0 2HXbL +b0 a8LX) +b0 w9uB: +b0 p\|p< +b0 L!mah +b0 tfo(b +b0 0xQ=% +sPhantomConst(\"0..=8\") {]-7b +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) _+{*U +sHdlNone\x20(0) ]MN.k +sRead\x20(0) sM,ig +b0 =Fu[V +b0 kv*+i +b0 jTB}~ +b0 5Dst$ +b0 [7tEQ +b0 .SWIf +b0 ?Me0A +b0 Fi_z" +b0 L6#}x +0&0Noi +0GcKtT +0C7R|D +0c'v6Y +0L2o7} +0Z6\#x +0"'OCX +013lt| +b0 HszjQ +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) MQ&&} +b0 OZ2^Q +sPhantomConst(\"0..4\") 09#6W +sHdlNone\x20(0) FzVU+ +sRead\x20(0) .D6*% +b0 5r}]; +b0 e"G$_ +b0 382OF +b0 7srDq +b0 S2Xv& +b0 K60=% +b0 &P];I +b0 s[>:S +b0 qSBc6 +07d+[x +0Xnk'W +0.C[8' +0L`]e0 +0/*xwY +0XN:$" +0f&U6 +b0 HD[R" +b0 =V9Jq +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":1,\"op_id_width\":8,\"address_range\":\"Full\"}) (B]kQ +0t[}s6 +sHdlNone\x20(0) hP{gt +b0 z:+(@ +0iE +0z~~Qk.t +b0 z\-#- +b0 Z=O^| +b0 `>e]R +b0 'B|ac +07?oLf +0~8qof +0SAr3k +0$l9b^ +02uYp& +0,36/r +0A?lPe +0T>3j| +b0 )Z68v +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) dBm[y +0uFc0' +sHdlNone\x20(0) U4@L' +sSuccess\x20(0) k[b|4 +sRead\x20(0) )%?'V +sGeneric\x20(0) Z0f\j +b0 MZ{gf +b0 4fJ+*i +b0 e<~Eb +b0 "|?fC +sPhantomConst(\"0..=8\") 9ZYIC +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) jO{Dq +sHdlNone\x20(0) 5&97& +sRead\x20(0) 8:%R9 +b0 Sr98H +b0 #fTp; +b0 ]&V$] +b0 I,dhN +b0 `7~"5 +0$e>rg +0)Z0Fs +0H];UQ +0.m6,b +b0 "Q^x_ +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) aE%(j +09"'Jr +sHdlNone\x20(0) n:-3L +sSuccess\x20(0) v3h>^ +sRead\x20(0) 2Y_0v +sGeneric\x20(0) 4j02? +b0 $VB%, +b0 zydP\ +b0 ]l{;7 +b0 4n~n8 +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) N_C[d +0H:0@M +sHdlNone\x20(0) |6zh: +b0 Nnv +0eI<6i +0Lc>f/ +0~#X87 +0MuvtB +0i3rnI +0I'q_? +0)t{[U +b0 |bTLs +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) w&S5S +0r9Nnr +sHdlNone\x20(0) ]Ej[\ +sSuccess\x20(0) {*ZH. +sRead\x20(0) 0WC)D +sGeneric\x20(0) Fi>dZ +b0 98zvW +b0 *x=!b +b0 ;-Wz} +b0 9'-5 +b0 le/]y +b0 AA3J3 +b0 4x/E{ +b0 ! +b0 cb-10 +b0 mn{ik +b0 Uz[0U +b0 AZ!Wg +sPhantomConst(\"0..=8\") ^=A2D +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) (0rdC +0'ohSl" +1q[z5A" +sHdlNone\x20(0) O>A\0" +0Xvg +0jM}qk +0Uf>vg" +1|GaPb +1>hk?I +03To8{ +0cy_"a +b0 )6skj +0'ohSl +1q[z5A +sHdlNone\x20(0) O>A\0 +0Xw:- +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) {NH:- +sHdlSome\x20(1) 4Z4x8 +sRead\x20(0) iTh$> +b0 EaRqh +b0 $Uo]g +b0 BS*a> +b0 jZ)fY +b0 [[(kn +0t.lS# +0zr4o9 +0H3A]g +0oJYjk +b0 8&p?/ +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) _[f9R +b0 m{*__ +sSuccess\x20(0) l[fye +sRead\x20(0) k:{2w +sGeneric\x20(0) V)Q)? +b0 [.>| +b0 EYP&Z +b0 7zb]V +b0 vhAS^ +b0 S0PWH +b0 &\y)U +b0 ]]u/b +b0 8"[Uj +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) 3j_%Y +0,f/D] +1(*n +b0 ]s1rd +b0 xS@qB +0f3iRp +0$yjZ, +0zmzdN +0,f`F+ +0LK"UV +0bc2~. +07_Bvx +03\"Nj +b0 {*%0k +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) ~{8K0 +0c>U|% +sHdlNone\x20(0) }JY0H +sSuccess\x20(0) ^udcB +sRead\x20(0) f?~C8 +sGeneric\x20(0) ='~t/ +b0 LF4%[ +b0 ?hS@| +b0 Z +sHdlNone\x20(0) m(9Y, +b0 |k +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) 7q$j3 +sHdlNone\x20(0) @Z +sRead\x20(0) qzT.O +b0 +W<2 +b0 }[w5S +b0 @eTQ| +b0 WNNgC +b0 Ej|;& +0Bp_CT +0^u,ix +0G+>7W +0.=AZ* +b0 2pyaqg +sRead\x20(0) ",DB3h +1>>\@Q +sHdlNone\x20(0) p#h%k +sRead\x20(0) 4OS6x +b0 wZ#~{ +b0 owJuR +b0 Cj>06 +b0 Bllp/ +b0 Q}gw? +b0 r+qf> +b0 NHEO? +b0 ;+k/C +b0 *D^^" +0%OVG~ +0P215H +09.vvP +0-}sQa +0Zbf'q +0os5&Y +0)lYu@ +0(dA6b +b0 `^n[, +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) z*"5J +0iR$H[ +sHdlNone\x20(0) X!c#K +sSuccess\x20(0) 1QvrF +sRead\x20(0) jUA{4 +sGeneric\x20(0) [3\kk +b0 bO~O' +b0 D##_H +b0 VNr(c +b0 r+q"E +b0 DMTaz +b0 zkhtj +b0 uc'5" +b0 #6}y{ +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) }7kxz +0yEvWo +sHdlNone\x20(0) {S{+O +b0 v>{58 +b0 To[FQ +b0 `/4zP +b0 [KEF: +b0 \:f[C +b0 *Q{Y# +b0 e"`qK +b0 Zz-H= +b0 h;1CX +sPhantomConst(\"0..=8\") _$]kF +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) t<)Eb +sHdlNone\x20(0) WaG') +sRead\x20(0) Yx+[Q +b0 KT$)+ +b0 fQk.t" +b0 z\-#-" +b0 Z=O^|" +b0 `>e]R" +b0 'B|ac" +07?oLf" +0~8qof" +0SAr3k" +0$l9b^" +02uYp&" +0,36/r" +0A?lPe" +0T>3j|" +b0 )Z68v" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) dBm[y" +0uFc0'" +sHdlNone\x20(0) U4@L'" +sSuccess\x20(0) k[b|4" +sRead\x20(0) )%?'V" +sGeneric\x20(0) Z0f\j" +b0 MZ{gf" +b0 4fJ+*i" +b0 e<~Eb" +b0 "|?fC" +sPhantomConst(\"0..=8\") 9ZYIC" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) jO{Dq" +sHdlNone\x20(0) 5&97&" +sRead\x20(0) 8:%R9" +b0 Sr98H" +b0 #fTp;" +0$e>rg" +b0 "Q^x_" +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) aE%(j" +09"'Jr" +sHdlNone\x20(0) n:-3L" +sSuccess\x20(0) v3h>^" +sRead\x20(0) 2Y_0v" +sGeneric\x20(0) 4j02?" +b0 $VB%," +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) N_C[d" +0H:0@M" +sHdlNone\x20(0) |6zh:" +b0 Nnv" +0eI<6i" +0Lc>f/" +0~#X87" +0MuvtB" +0i3rnI" +0I'q_?" +0)t{[U" +b0 |bTLs" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) w&S5S" +0r9Nnr" +sHdlNone\x20(0) ]Ej[\" +sSuccess\x20(0) {*ZH." +sRead\x20(0) 0WC)D" +sGeneric\x20(0) Fi>dZ" +b0 98zvW" +b0 *x=!b" +b0 ;-Wz}" +b0 9'-5" +b0 le/]y" +0w'51o" +b0 f" +b0 cb-10" +b0 mn{ik" +b0 Uz[0U" +b0 AZ!Wg" +sPhantomConst(\"0..=8\") ^=A2D" +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) (0rdC" +0'ohSl$ +1q[z5A$ +sHdlNone\x20(0) O>A\0$ +0Xvg# +0jM}qk" +0Uf>vg$ +1|GaPb" +1>hk?I" +03To8{" +0cy_"a" +b0 )6skj" +0'ohSl# +1q[z5A# +sHdlNone\x20(0) O>A\0# +0X/ +b0 ~0#Je +b0 xkXiO +05gjp[ +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) *S7*~ +0S#TWr +0T2q>B +b0 *B4E0 +b0 3S7WO +0tn +0$[wv= +b0 "2_9l +b0 @@)-G +0pAnAd +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) NdYm} +0'H4D&" +0-y1}:" +b0 Rzg.[" +b0 yYt:L" +0/yppY" +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) {NH:-" +04'qCV +0PWYG* +b0 y)j'q +b0 97u:z +06kJ@Y +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) k*?v0 +08`]ji +0YgAEs +b0 73$!^ +b0 $5h$6 +0hAq)G +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) f%}S^ +0i_"+u +0f/^q3 +b0 #c2~e +b0 ,g{ZD +0MK\{x +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) /{;*1 +sHdlSome\x20(1) 4Z4x8" +sRead\x20(0) iTh$>" +b0 EaRqh" +b0 $Uo]g" +0t.lS#" +b0 8&p?/" +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) _[f9R" +b0 m{*__" +sSuccess\x20(0) l[fye" +sRead\x20(0) k:{2w" +sGeneric\x20(0) V)Q)?" +b0 [.>|!" +b0 EYP&Z" +b0 7zb]V" +b0 vhAS^" +b0 S0PWH" +b0 &\y)U" +b0 ]]u/b" +b0 8"[Uj" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) 3j_%Y" +0,f/D]" +1(*n" +b0 ]s1rd" +b0 xS@qB" +0f3iRp" +0$yjZ," +0zmzdN" +0,f`F+" +0LK"UV" +0bc2~." +07_Bvx" +03\"Nj" +b0 {*%0k" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) ~{8K0" +0c>U|%" +sHdlNone\x20(0) }JY0H" +sSuccess\x20(0) ^udcB" +sRead\x20(0) f?~C8" +sGeneric\x20(0) ='~t/" +b0 LF4%[" +b0 ?hS@|" +b0 Z" +sHdlNone\x20(0) m(9Y," +b0 |k" +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) 7q$j3" +sHdlNone\x20(0) @Z" +sRead\x20(0) qzT.O" +b0 +W<2!" +b0 }[w5S" +0Bp_CT" +b0 2pyaqg" +sRead\x20(0) ", +b0 8o]vK +b0 T5k5x +b0 UW~DU +b0 &X^|* +b0 0wJ^} +03`\nb +0l{$kj +0;S^U| +0VfyoK +0DvX6A +0I2dd_ +0V(%D. +0_uXDb +b0 'z$t< +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) NtLP9 +0IQt>v +sHdlNone\x20(0) VmI%y +sSuccess\x20(0) IKB)% +sRead\x20(0) +|FzD +sGeneric\x20(0) fas): +b0 mg"r] +b0 h!s^i +b0 D'gKs +b0 %zV12 +b0 2buNY +b0 B>OKu +b0 &'-QM +b0 ?+F%y +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) zqOzP +0;H~?) +sHdlNone\x20(0) fv6%d +b0 ({53A +b0 FK[+c +b0 2Z6r~ +b0 '$`LB +b0 MpmDr +b0 qXb)4 +b0 3+mZM +b0 =.UVZ +b0 ,iC/t +sPhantomConst(\"0..=8\") uX9~O +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) C[e/B +sHdlNone\x20(0) W/\W+ +sRead\x20(0) X= +b0 T9vmz +b0 ;a+`< +b0 &{pV0 +b0 MLaH6 +b0 C\d2; +b0 A!''D +sPhantomConst(\"0..=8\") sjj!t +sPhantomConst({\"log2_bus_width_in_bytes\":0,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":12288,\"size\":256}}}) 7EHvW +0D)Up[ +1x~j-j +sHdlNone\x20(0) D%xS, +sRead\x20(0) W_75= +b0 ]$c0\ +b0 :4>j +b0 /n^.0 +b0 Gy|$z +b0 *-GzR +b0 dv}6` +b0 |MzD| +b0 +#4Ae +b0 7DG.0 +0swSnp +00!}9_ +0Eu[4Z +0v(pFI +0G(L]# +0a'Z"M +0woy8t +0O:-Ou +b0 DlAX? +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) 3W|p* +b0 [$u%~ +sPhantomConst(\"0..4\") kYdkn +15\}~> +sHdlNone\x20(0) z[d;i +sRead\x20(0) 'vusN +b0 $>+uK +b0 zCQ"e +b0 t8^C6 +b0 XX|nl +b0 8Y%Wk +b0 54RLx +b0 U"-'. +b0 =KKpu +b0 e$Wq| +0}=#gh +06f{rQ +0UlT#C +0]XK,Q +0b4plV +0O0fXd +0#c].s +03\e(. +b0 vQk;& +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) Zgh@V +b0 ?`R@B +sPhantomConst(\"0..4\") 0}{|# +0t"bJH +0.sMPc +s0 Fi)a" +1t%>FQ +0a:ro< +sRead\x20(0) BQq`v +b0 X;(;e +b0 bII(} +b0 IMrY` +b0 +XouE +b0 QZPbV +b0 =LM+p +b0 1|jHy +b0 A"hJ: +b0 ?b`Z} +0ht@AC +095qQh +00)#7N +0o{5.4 +0m`EXj +0/=RNL +0XR14A +0-/RU< +b0 8G`:M +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) l|04C +b0 139p] +sPhantomConst(\"0..4\") "dFO3 +s0 Eec_# +0PLEF3 +0.34:S +sRead\x20(0) z@&Tn +b0 FkI@> +b0 B4^}F +b0 `iD'f +b0 {_r@k +b0 Ps-7W +b0 2DzS} +b0 b*)<` +b0 C+?w; +b0 Qgp9] +0xL}T[ +0P>7{t +0F?jn> +0s*%n' +0o$4A8 +0L32DC +0ZRo,\ +0EZt+2 +b0 vEdKE +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) \@u,: +b0 Ha9z2 +sPhantomConst(\"0..4\") 1ffCl +1Q,J^5 +1ffSyY +14dt=j +1)Cvf\ +1#x4t# +19wSE" +1%zM|B +1ntM]@ +1%R1@3 +1eS,c@ +1vD^,9 +1bj$RP +1e155L +1m;aG\ +1dvGIO +1mX16b +1_+0bR +1A/-lz +1E#PuA +1o]hNF +s0 1201; +s0 z6UdP +0.T-}[ +0NG-f; +0_eUF] +0[TO.D +0_eUF]" +14 +00'"+n +0v+*l9 +0^ +0O`-ue +b0 Yi2hP +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) j_laO +b0 k-bFV +sPhantomConst(\"0..4\") 1Sz{4 +s0 0T17D +0SEzxV +1M36~K +sHdlNone\x20(0) BMS_* +sRead\x20(0) *{sP( +b0 _0e[y +b0 4r8@a +b0 _`'$= +b0 Cz0|, +b0 D$X,j +b0 h]_9W +b0 mA`Sf +b0 N%X'~ +b0 !lQ[l +0-_2Ng +0RZbuG +0%uw+, +0Q1HE< +03LJN^ +0\8.Cs +0ZFqzE +0?)"O@ +b0 [>BA< +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) f~RD$ +b0 4z-H2 +sPhantomConst(\"0..4\") xOedc +1`?E&S +sHdlNone\x20(0) 4{-zs +sRead\x20(0) *TaVw +b0 ;tO$C +b0 $XA}i +b0 F;oLB +b0 Q=;=] +sPhantomConst(\"0..4\") :lV`' +0D)Up[" +1x~j-j" +sHdlNone\x20(0) D%xS," +b0 Q&d`s +sPhantomConst(\"0..4\") J3qBr +15\}~>" +sHdlNone\x20(0) z[d;i" +b0 YNu#3 +sPhantomConst(\"0..4\") z.*z9 +0t"bJH" +b0 .sMPc" +b0 Fi)a"" +1t%>FQ" +0a:ro<" +b0 h4|FL +sPhantomConst(\"0..4\") 2.h"; +b0 Eec_#" +0PLEF3" +0.34:S" +b0 v&*FG +sPhantomConst(\"0..4\") [jY]& +1kBn0e +b0 1201;" +b0 z6UdP" +0.T-}[" +0NG-f;" +0_eUF]# +0[TO.D" +0_eUF]$ +1x2 +b0 R\O,0 +sPhantomConst(\"0..4\") q}+|l +1zFkc^ +sHdlNone\x20(0) \^:|R +b0 X=:J. +sPhantomConst(\"0..4\") cNT/Y +0I2+~X +b0 Ly1ZZ +0W?Hp~ +1_]m=\ +sHdlNone\x20(0) wjjEV +sRead\x20(0) mglkY +b0 1y!RS +b0 yf$TD +b0 _kDIS +b0 C(77z +b0 vy{V< +b0 79H@q +b0 7yPfs +b0 \"@Q7 +b0 |bsUw +0Mv+$0 +0W/x9+ +0m)\5f +0Qo^bw +0/t.wP +0g?u_Y +0USD_s +0[KPI* +b0 {T7hv +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) N`B*t +11;JQ^ +sHdlNone\x20(0) e.~]E +sSuccess\x20(0) "M,X; +sRead\x20(0) !DxRJ +sGeneric\x20(0) \ZSl] +b0 c5W@* +b0 ?4QjV +b0 ;|Aqn +b0 f448; +b0 SX+N\ +b0 ci0zj +b0 Utm?q +b0 1?.bq +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) ANd]< +09C+iW +sHdlNone\x20(0) 4wB3; +b0 G%Xf" +b0 ^hV1y +b0 A_Mcu +b0 M8Jbj +b0 OyJzS +b0 .PiLo +b0 F(}+6 +b0 n_V=D +b0 jpsY) +sPhantomConst(\"0..=8\") 1#HFy +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":\"Full\"}) :MjuY +sHdlNone\x20(0) np$oq +sRead\x20(0) +F8oo +b0 c5fPr +b0 oz/?< +b0 -^N!& +b0 j.CJz +b0 xZ6w$ +b0 I!IyC +b0 !~yml +b0 ;%1YG +b0 #u^v[ +0xw3*n +03MmE- +0J6"p\ +04y0A> +0"=3`U +0|/[bs +0ITlw\ +0Xmq~1 +b0 =dq8M +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) jZuCk +0>6&v2 +sHdlNone\x20(0) 'SG%{ +sSuccess\x20(0) ?l*T; +sRead\x20(0) ZWG)3 +sGeneric\x20(0) EDNkm +b0 r[Pix +b0 Xq(iG +b0 gUg1| +b0 )4f{a +b0 >7g3p +b0 B(b7B +b0 r{D0O +b0 [/Z>s +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) ceQp% +0JewCi +sHdlNone\x20(0) ]lv__ +b0 qciRv +b0 &i=E< +b0 -B)\; +b0 4REHN +b0 |o1m% +b0 6cwGg +b0 nSY:X +b0 Ve94A +b0 )+f{_ +sPhantomConst(\"0..=8\") r)?`J +sPhantomConst({\"log2_bus_width_in_bytes\":3,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":4096,\"size\":4096}}}) Y8V6| +sHdlNone\x20(0) BiRsb +sRead\x20(0) lpY:~ +b0 Olcb@ +b0 B*Yy4 +b0 ~A_TB +b0 FoK"Z +b0 1k]ct +0h@V4t +0:"U|2 +0=(^$` +0^LobZ +b0 U`oQ* +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) 8?PW` +04|.Py +sHdlNone\x20(0) JGh2) +sSuccess\x20(0) x4q}C +sRead\x20(0) C\_/W +sGeneric\x20(0) rt!2l +b0 T:gt\ +b0 RlG5V +b0 ZdsQG +b0 #S~+R +sPhantomConst({\"log2_bus_width_in_bytes\":2,\"queue_capacity\":8,\"op_id_width\":8,\"address_range\":{\"Limited\":{\"start\":8192,\"size\":16}}}) 0/SmU +0&'Zc6 +sHdlNone\x20(0) eS-=. +b0 |Uk!E +b0 q>.SI +b0 Z~CdF +b0 @piu' +b0 ,`j;j +b0 Wg6&v2 +sHdlSome\x20(1) ]lv__ +19Kr<," +sHdlSome\x20(1) Od;kq" +1"T*hK +sHdlSome\x20(1) d&8T= +1Ql_>c +sHdlSome\x20(1) U|% +sHdlSome\x20(1) m(9Y, +1nIQRw +sHdlSome\x20(1) G&Err +1iR$H[ +sHdlSome\x20(1) {S{+O +1;k;N1 +sHdlSome\x20(1) D2G)" +14|.Py +sHdlSome\x20(1) eS-=. +19Kr<,# +sHdlSome\x20(1) Od;kq# +15=*5a +sHdlSome\x20(1) Pm+T_ +1po3;M +sHdlSome\x20(1) ;5dr1 +1uFc0'" +sHdlSome\x20(1) /FKc]" +19"'Jr" +sHdlSome\x20(1) |6zh:" +1r9Nnr" +sHdlSome\x20(1) vA'i[" +1oPWNj" +sHdlSome\x20(1) Rr;aY" +1c>U|%" +sHdlSome\x20(1) m(9Y," +1nIQRw" +sHdlSome\x20(1) G&Err" +1IQt>v +sHdlSome\x20(1) fv6%d +1Q$%O3 +sHdlSome\x20(1) vdQ/" +1@RUuM +sHdlSome\x20(1) ,DF\+ +#500000 +17Z.$. +13v&1D" +13v&1D +1b}F_+ +1t,f{i +1b}F_+" +1,kkUh +1b}F_+# +1U\\gA +1b!RoJ +1[Qu?z +1nZ^[< +1'ohSl" +1{fq,{ +1-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-o7 +1V_5A^ +1A+uK +1}=#gh +16f{rQ +1UlT#C +1]XK,Q +1b4plV +1O0fXd +1#c].s +13\e(. +1t"bJH +1PLEF3 +b1111111111111111111111111111111111111111111111110000000000000000 FkI@> +1xL}T[ +1P>7{t +1F?jn> +1s*%n' +1o$4A8 +1L32DC +1ZRo,\ +1EZt+2 +1NG-f; +1_eUF] +1[TO.D +1_eUF]" +b1111111111111111111111111111111111111111111111110000000000000000 xlMx: +1g+-/g +1ASv>4 +10'"+n +1v+*l9 +1^ +1O`-ue +sHdlSome\x20(1) BMS_* +b1111111111111111111111111111111111111111111111110000000000000000 _0e[y +1-_2Ng +1RZbuG +1%uw+, +1Q1HE< +13LJN^ +1\8.Cs +1ZFqzE +1?)"O@ +sHdlSome\x20(1) 4{-zs +b1111111111111111111111111111111111111111111111110000000000000000 ;tO$C +1!4ltE +1:ICC5 +1t$j8c +1[Z\/3 +1GI_F7 +1!`HGI +15MMr$ +1^iQ-i +1|9c(5 +sHdlSome\x20(1) D%xS," +1PLEF3" +1NG-f;" +1_eUF]# +sHdlSome\x20(1) Kq>x2 +sHdlSome\x20(1) wjjEV +b1111111111111111111111111111111111111111111111110000000000000000 1y!RS +1Mv+$0 +1W/x9+ +1m)\5f +1Qo^bw +1/t.wP +1g?u_Y +1USD_s +1[KPI* +19C+iW +sHdlSome\x20(1) np$oq +b1111111111111111111111111111111111111111111111110000000000000000 c5fPr +1xw3*n +13MmE- +1J6"p\ +14y0A> +1"=3`U +1|/[bs +1ITlw\ +1Xmq~1 +#1000000 +07Z.$. +0}MTh| +03v&1D" +0.IY;M" +03v&1D +0.IY;M +0b}F_+ +0]2Q-p +0t,f{i +0t[3h= +0b}F_+" +0]2Q-p" +0,kkUh +09Jb6Z +0b}F_+# +0]2Q-p# +0U\\gA +0k@&rZ +0b!RoJ +0XL7[o +0[Qu?z +0PK0LO +0nZ^[< +0$`i9} +0'ohSl" +0q[z5A" +0{fq,{ +0-oDB3h +0>>\@Q +0[Qu?z" +0PK0LO" +0nZ^[<" +0$`i9}" +0'ohSl$ +0q[z5A$ +0{fq,{" +0-o.v +1iZU?z +1{}m6q +1Z1CM. +1Y;{RD +1#4eK< +1PBL"6 +1+9?iP +b0 5}.LR +s0 I3yzX +b0 tOH2~ +s0 DB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-o7 +0V_5A^ +0A+uK +0}=#gh +06f{rQ +0UlT#C +0]XK,Q +0b4plV +0O0fXd +0#c].s +03\e(. +0t"bJH +0PLEF3 +b0 FkI@> +0xL}T[ +0P>7{t +0F?jn> +0s*%n' +0o$4A8 +0L32DC +0ZRo,\ +0EZt+2 +0NG-f; +0_eUF] +0[TO.D +0_eUF]" +b0 xlMx: +0g+-/g +0ASv>4 +00'"+n +0v+*l9 +0^ +0O`-ue +sHdlNone\x20(0) BMS_* +b0 _0e[y +0-_2Ng +0RZbuG +0%uw+, +0Q1HE< +03LJN^ +0\8.Cs +0ZFqzE +0?)"O@ +sHdlNone\x20(0) 4{-zs +b0 ;tO$C +0!4ltE +0:ICC5 +0t$j8c +0[Z\/3 +0GI_F7 +0!`HGI +05MMr$ +0^iQ-i +0|9c(5 +sHdlNone\x20(0) D%xS," +0PLEF3" +0NG-f;" +0_eUF]# +sHdlNone\x20(0) Kq>x2 +sHdlNone\x20(0) wjjEV +b0 1y!RS +0Mv+$0 +0W/x9+ +0m)\5f +0Qo^bw +0/t.wP +0g?u_Y +0USD_s +0[KPI* +sHdlNone\x20(0) np$oq +b0 c5fPr +0xw3*n +03MmE- +0J6"p\ +04y0A> +0"=3`U +0|/[bs +0ITlw\ +0Xmq~1 +b1 0=E8% +b1 7Y>vV +b1 vc&UB +b1 )+f{_ +#2000000 +07Z.$. +03v&1D" +03v&1D +0b}F_+ +0t,f{i +0b}F_+" +0,kkUh +0b}F_+# +0U\\gA +0b!RoJ +0[Qu?z +0nZ^[< +0'ohSl" +0{fq,{ +0-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-ol^L1 +1t"bJH" +1[TO.D" +1_eUF]$ +1I2+~X +sHdlSome\x20(1) e.~]E +sError\x20(1) "M,X; +sHdlSome\x20(1) 'SG%{ +sError\x20(1) ?l*T; +#4000000 +07Z.$. +03v&1D" +03v&1D +0b}F_+ +0t,f{i +0b}F_+" +0,kkUh +0b}F_+# +0U\\gA +0b!RoJ +0[Qu?z +0nZ^[< +0'ohSl" +0{fq,{ +0-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-ovV +b0 vc&UB +b0 )+f{_ +#5000000 +07Z.$. +03v&1D" +03v&1D +0b}F_+ +0t,f{i +0b}F_+" +0,kkUh +0b}F_+# +0U\\gA +0b!RoJ +0[Qu?z +0nZ^[< +0'ohSl" +0{fq,{ +0-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-o7 +b1 f*.L1 +sHdlSome\x20(1) zK+hs +b1000000000000 0F=tx +1`L:Kx +b1 I5xTL +sHdlSome\x20(1) H)GyP +b1000000000000 0]FS] +1[x"|) +b1 _InNh +sHdlSome\x20(1) bx7Ir +b1000000000000 8Yc\q +1voHP. +b1 !Sr|6 +sHdlSome\x20(1) ]MN.k +b1000000000000 =Fu[V +1&0Noi +b1 HszjQ +sHdlSome\x20(1) D%xS, +b1000000000000 ]$c0\ +1swSnp +b1 DlAX? +sHdlSome\x20(1) z[d;i +b1000000000000 $>+uK +1}=#gh +b1 vQk;& +1t"bJH +1PLEF3 +b1000000000000 FkI@> +1xL}T[ +b1 vEdKE +1NG-f; +1_eUF] +1[TO.D +1_eUF]" +b1000000000000 xlMx: +1g+-/g +b1 Yi2hP +sHdlSome\x20(1) BMS_* +b1000000000000 _0e[y +1-_2Ng +b1 [>BA< +sHdlSome\x20(1) 4{-zs +b1000000000000 ;tO$C +1!4ltE +b1 pLqOm +1|9c(5 +sHdlSome\x20(1) D%xS," +1PLEF3" +1NG-f;" +1_eUF]# +sHdlSome\x20(1) Kq>x2 +sHdlSome\x20(1) wjjEV +b1000000000000 1y!RS +1Mv+$0 +b1 {T7hv +sHdlSome\x20(1) np$oq +b1000000000000 c5fPr +1xw3*n +b1 =dq8M +#7000000 +07Z.$. +03v&1D" +03v&1D +0b}F_+ +0t,f{i +0b}F_+" +0,kkUh +0b}F_+# +0U\\gA +0b!RoJ +0[Qu?z +0nZ^[< +0'ohSl" +0{fq,{ +0-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-o.v +0iZU?z +0{}m6q +0Z1CM. +0Y;{RD +0#4eK< +0PBL"6 +0+9?iP +b1 5}.LR +s0 I3yzX +b0 tOH2~ +s0 DB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-o7 +1V_5A^ +b10 f*.L1 +0`L:Kx +1c@wv- +b10 I5xTL +0[x"|) +11FIL0 +b10 _InNh +0voHP. +1_GjOE +b10 !Sr|6 +0&0Noi +1GcKtT +b10 HszjQ +0swSnp +10!}9_ +b10 DlAX? +0}=#gh +16f{rQ +b10 vQk;& +0xL}T[ +1P>7{t +b10 vEdKE +0g+-/g +1ASv>4 +b10 Yi2hP +0-_2Ng +1RZbuG +b10 [>BA< +0!4ltE +1:ICC5 +b10 pLqOm +0Mv+$0 +1W/x9+ +b10 {T7hv +0xw3*n +13MmE- +b10 =dq8M +sSuccess\x20(0) ATlSR" +b1010100 lqb+8" +sSuccess\x20(0) ATlSR +b1010100 lqb+8 +sSuccess\x20(0) K4!SI +b1010100 zhnfr +b1 8ibWx +b1 0=E8% +sSuccess\x20(0) OO)vV +sSuccess\x20(0) ~9Ybc +b1010100 [}N3Q +sSuccess\x20(0) >l^L1 +b1010100 n]!VA +b1 FdK8l +b1 vc&UB +sSuccess\x20(0) "M,X; +b1010100 c5W@* +sSuccess\x20(0) ?l*T; +b1010100 r[Pix +b1 qciRv +b1 )+f{_ +#8000000 +07Z.$. +03v&1D" +03v&1D +0b}F_+ +0t,f{i +0b}F_+" +0,kkUh +0b}F_+# +0U\\gA +0b!RoJ +0[Qu?z +0nZ^[< +0'ohSl" +0{fq,{ +0-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-o.v +1iZU?z +0{}m6q +0Z1CM. +0Y;{RD +0#4eK< +0PBL"6 +0+9?iP +b10 5}.LR +s0 I3yzX +b0 tOH2~ +s0 DB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-o+uK +06f{rQ +b0 vQk;& +0t"bJH +0PLEF3 +b0 FkI@> +0P>7{t +b0 vEdKE +0NG-f; +0_eUF] +0[TO.D +0_eUF]" +b0 xlMx: +0ASv>4 +b0 Yi2hP +sHdlNone\x20(0) BMS_* +b0 _0e[y +0RZbuG +b0 [>BA< +sHdlNone\x20(0) 4{-zs +b0 ;tO$C +0:ICC5 +b0 pLqOm +0|9c(5 +sHdlNone\x20(0) D%xS," +0PLEF3" +0NG-f;" +0_eUF]# +sHdlNone\x20(0) Kq>x2 +sHdlNone\x20(0) wjjEV +b0 1y!RS +0W/x9+ +b0 {T7hv +sHdlNone\x20(0) np$oq +b0 c5fPr +03MmE- +b0 =dq8M +b10 8ibWx +b10 M|25f +b10 FdK8l +b10 qciRv +#9000000 +07Z.$. +03v&1D" +03v&1D +0b}F_+ +0t,f{i +0b}F_+" +0,kkUh +0b}F_+# +0U\\gA +0b!RoJ +0[Qu?z +0nZ^[< +0'ohSl" +0{fq,{ +0-oDB3h +0[Qu?z" +0nZ^[<" +0'ohSl$ +0{fq,{" +0-oDB3h +1[Qu?z" +1nZ^[<" +1'ohSl$ +1{fq,{" +1-o) -> u8 { + let index = delay_sequence_index.get(); + delay_sequence_index.set(delay_sequence_index.get().wrapping_add(1)); + // make a pseudo-random number deterministically based on index + let random = index + .wrapping_add(1) + .wrapping_mul(0x8c16a62518f86883) // random prime + .rotate_left(32) + .wrapping_mul(0xf807b7df2082353d) // random prime + .rotate_right(60); + const DELAYS: &[u8; 0x20] = &[ + 0, 0, 0, 0, 0, 0, 0, 0, // + 1, 1, 1, 1, 1, 1, 1, 1, // + 2, 2, 2, 2, 2, 2, 2, 2, // + 3, 3, 3, 3, 4, 5, 6, 20, // + ]; + DELAYS[(random & 0x1F) as usize] +} + +#[hdl_module(extern)] +fn mock_memory(memory: Memory) { + let Memory { config, contents } = memory; + #[hdl] + let cd: ClockDomain = m.input(); + #[hdl] + let input_interface: MemoryInterface> = + m.input(MemoryInterface[config]); + m.register_clock_for_past(cd.clk); + #[hdl] + async fn run( + cd: Expr, + input_interface: Expr>>, + config: PhantomConst, + contents: Interned, + delay_sequence_index: &Cell, + mut sim: ExternModuleSimulationState, + ) { + #[derive(Debug)] + struct Op { + cycles_left: u8, + op_id: SimValue, + finish: SimValue>>, + } + let mut ops = VecDeque::::with_capacity(config.get().queue_capacity.get()); + let finish_ty = input_interface.ty().finish.data.HdlSome; + loop { + for op in &mut ops { + op.cycles_left = op.cycles_left.saturating_sub(1); + } + let next_op_ids_ty = input_interface.ty().next_op_ids.HdlSome; + sim.write( + input_interface.next_op_ids, + #[hdl(sim)] + (input_interface.ty().next_op_ids).HdlSome( + next_op_ids_ty + .from_iter_sim( + next_op_ids_ty.element().zero(), + ops.iter().map(|op| &op.op_id), + ) + .expect("known to fit"), + ), + ) + .await; + if let Some(Op { + cycles_left: 0, + op_id: _, + finish, + }) = ops.front() + { + sim.write( + input_interface.finish.data, + #[hdl(sim)] + (input_interface.ty().finish.data).HdlSome(finish), + ) + .await; + } + sim.write_bool( + input_interface.start.ready, + ops.len() < config.get().queue_capacity.get(), + ) + .await; + sim.wait_for_clock_edge(cd.clk).await; + if sim + .read_past_bool(input_interface.finish.ready, cd.clk) + .await + { + ops.pop_front_if(|op| op.cycles_left == 0); + } + if sim + .read_past_bool(input_interface.start.ready, cd.clk) + .await + { + #[hdl(sim)] + if let HdlSome(start) = sim.read_past(input_interface.start.data, cd.clk).await { + #[hdl(sim)] + let MemoryOperationStart::<_> { + kind, + addr, + write_data, + rw_mask, + op_id, + config: _, + } = start; + let mut error = false; + let mut read_data = vec![0u8; finish_ty.read_data.len()]; + #[hdl(sim)] + match &kind { + MemoryOperationKind::Read => { + for (i, v) in read_data.iter_mut().enumerate() { + if *rw_mask[i] { + let addr = addr.as_int().wrapping_add(i as u64); + let offset = + addr.wrapping_sub(config.get().address_range.start().0); + if !config.get().address_range.contains(addr) { + error = true; + break; + } + *v = contents.as_bytes()[offset as usize]; + println!( + "reading byte at {addr:#x} (offset={offset:#x}) -> {v:#x} (contents={contents:?})", + ); + } + } + if !error { + println!( + "read chunk at {addr:#x}: {:#x?}", + std::fmt::from_fn(|f| f + .debug_map() + .entries( + read_data + .iter() + .enumerate() + .filter_map(|(i, &v)| rw_mask[i].then(|| (i, v))) + ) + .finish()), + addr = addr.as_int(), + ); + } + } + MemoryOperationKind::Write => { + todo!("write {write_data:?}"); + } + } + let finish_kind = if error { + read_data.fill(0); + #[hdl(sim)] + MemoryOperationFinishKind.Error( + #[hdl(sim)] + MemoryOperationErrorKind.Generic(), + ) + } else { + #[hdl(sim)] + MemoryOperationFinishKind.Success(kind) + }; + ops.push_back(Op { + cycles_left: get_next_delay(delay_sequence_index), + op_id, + finish: #[hdl(sim)] + MemoryOperationFinish::<_> { + kind: finish_kind, + read_data, + config, + }, + }); + } + } + } + } + m.extern_module_simulation_fn( + (cd, input_interface, config, contents), + async |(cd, input_interface, config, contents), mut sim| { + // intentionally have a different sequence each time we're reset + let delay_sequence_index = Cell::new(0); + sim.resettable( + cd, + async |mut sim| { + sim.write( + input_interface.next_op_ids, + #[hdl(sim)] + (input_interface.ty().next_op_ids).HdlNone(), + ) + .await; + sim.write_bool(input_interface.start.ready, false).await; + sim.write( + input_interface.finish.data, + #[hdl(sim)] + (input_interface.ty().finish.data).HdlNone(), + ) + .await; + }, + |sim, ()| { + run( + cd, + input_interface, + config, + contents, + &delay_sequence_index, + sim, + ) + }, + ) + .await + }, + ); +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +struct Memory { + contents: Interned, + config: PhantomConst, +} + +impl Memory { + fn new( + contents: impl AsRef, + log2_bus_width_in_bytes: u8, + address_range: AddressRange, + ) -> Self { + Self { + contents: contents.as_ref().intern(), + config: PhantomConst::new_sized(MemoryInterfaceConfig::new( + log2_bus_width_in_bytes, + 8, + FETCH_BLOCK_ID_WIDTH, + address_range, + )), + } + } +} + +#[hdl_module(extern)] +fn mock_cpu(memories: Interned<[Memory]>) { + const LOG2_BUS_WIDTH: u8 = 3; + const BUS_WIDTH: usize = 1 << LOG2_BUS_WIDTH; + let config = PhantomConst::new_sized(MemoryInterfaceConfig::new( + LOG2_BUS_WIDTH, + 8, + FETCH_BLOCK_ID_WIDTH, + AddressRange::Full, + )); + #[hdl] + let cd: ClockDomain = m.input(); + #[hdl] + let output_interface: MemoryInterface> = + m.output(MemoryInterface[config]); + #[hdl] + let finished: Bool = m.output(); + m.register_clock_for_past(cd.clk); + #[derive(PartialEq)] + struct Op { + addr: u64, + read_mask: [bool; BUS_WIDTH], + } + impl fmt::Debug for Op { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { addr, read_mask } = self; + f.debug_struct("Op") + .field("addr", &fmt::from_fn(|f| write!(f, "{addr:#x}"))) + .field("read_mask", read_mask) + .finish() + } + } + #[hdl] + async fn generator( + cd: Expr, + output_interface: Expr>>, + config: PhantomConst, + sequence: &[Op], + delay_sequence_index: &Cell, + mut sim: ExternModuleSimulationState, + ) { + println!("generator: start"); + let start_ty = MemoryOperationStart[config]; + for (op_index, op) in sequence.iter().enumerate() { + sim.write( + output_interface.start.data, + #[hdl(sim)] + (output_interface.ty().start.data).HdlNone(), + ) + .await; + let delay = get_next_delay(delay_sequence_index); + println!("generator: delay by {delay}"); + for i in 0..delay { + println!("generator: delay cycle {i}"); + sim.wait_for_clock_edge(cd.clk).await; + } + sim.write( + output_interface.start.data, + #[hdl(sim)] + (output_interface.ty().start.data).HdlSome( + #[hdl(sim)] + MemoryOperationStart::<_> { + kind: #[hdl(sim)] + MemoryOperationKind.Read(), + addr: op.addr, + write_data: &[0u8; BUS_WIDTH][..], + rw_mask: &op.read_mask[..], + op_id: op_index.cast_to(start_ty.op_id), + config, + }, + ), + ) + .await; + sim.wait_for_clock_edge(cd.clk).await; + while !sim + .read_past_bool(output_interface.start.ready, cd.clk) + .await + { + sim.wait_for_clock_edge(cd.clk).await; + } + } + } + #[hdl] + async fn checker( + cd: Expr, + output_interface: Expr>>, + config: PhantomConst, + sequence: &[Op], + memories: Interned<[Memory]>, + delay_sequence_index: &Cell, + sim: &mut ExternModuleSimulationState, + ) { + println!("checker: start"); + for op in sequence { + sim.write_bool(output_interface.finish.ready, false).await; + let delay = get_next_delay(delay_sequence_index); + println!("checker: delay {delay}"); + for _ in 0..delay { + sim.wait_for_clock_edge(cd.clk).await; + } + sim.write_bool(output_interface.finish.ready, true).await; + sim.wait_for_clock_edge(cd.clk).await; + let mut finish = loop { + #[hdl(sim)] + if let HdlSome(finish) = sim.read_past(output_interface.finish.data, cd.clk).await { + break finish; + } + sim.wait_for_clock_edge(cd.clk).await; + }; + let finish_unmasked = finish.clone(); + for (v, &mask) in finish.read_data.iter_mut().zip(&op.read_mask) { + if !mask { + *v = 0u8.to_sim_value(); // ignore outputs for ignored bytes + } + } + let mut expected_finish = memories + .iter() + .find(|m| m.config.get().address_range.contains(op.addr)) + .and_then( + |&Memory { + config: memory_config, + contents, + }| + -> Option<_> { + let mut read_data = [0u8; BUS_WIDTH]; + let mut first_enabled = None; + let mut last_enabled = None; + for (i, &mask) in op.read_mask.iter().enumerate() { + if mask { + first_enabled.get_or_insert(i); + last_enabled = Some(i); + read_data[i] = *contents.as_bytes().get( + usize::try_from( + op.addr.wrapping_add(i as u64).wrapping_sub( + memory_config.get().address_range.start().0, + ), + ) + .ok()?, + )?; + } + } + if let (Some(first_enabled), Some(last_enabled)) = + (first_enabled, last_enabled) + { + let log2_bus_width_in_bytes = + memory_config.get().log2_bus_width_in_bytes; + if first_enabled >> log2_bus_width_in_bytes + != last_enabled >> log2_bus_width_in_bytes + { + // this operation requires more than one operation at the final memory, + // so it gets turned into an error since we're using + // memory_interface_adapter_no_split + return None; + } + } + Some( + #[hdl(sim)] + MemoryOperationFinish::<_> { + kind: #[hdl(sim)] + MemoryOperationFinishKind.Success( + #[hdl(sim)] + MemoryOperationKind.Read(), + ), + read_data: &read_data[..], + config, + }, + ) + }, + ) + .unwrap_or_else(|| { + #[hdl(sim)] + MemoryOperationFinish::<_> { + kind: #[hdl(sim)] + MemoryOperationFinishKind.Error( + #[hdl(sim)] + MemoryOperationErrorKind.Generic(), + ), + read_data: &[0u8; BUS_WIDTH][..], + config, + } + }); + // make SimValue fill in the enum padding so they format the same + SimValue::bits_mut(&mut finish); + SimValue::bits_mut(&mut expected_finish); + assert!( + format!("{finish:#?}") == format!("{expected_finish:#?}"), + "op={op:#?}\nexpected_finish={expected_finish:#?}\n\ + finish={finish:#?}\nfinish_unmasked={finish_unmasked:#?}" + ); + } + } + m.extern_module_simulation_fn( + (cd, output_interface, finished, config, memories), + async |(cd, output_interface, finished, config, memories), mut sim| { + sim.write_bool(finished, false).await; + sim.write_bool(output_interface.finish.ready, false).await; + sim.write( + output_interface.start.data, + #[hdl(sim)] + (output_interface.ty().start.data).HdlNone(), + ) + .await; + + // intentionally have a different sequence each time we're reset + let generator_delay_sequence_index = Cell::new(1 << 63); + let checker_delay_sequence_index = Cell::new(1 << 62); + let mut sequence = Vec::new(); + sequence.push(Op { + addr: !0 << 16, + read_mask: [true; _], + }); + for (i, memory) in memories.iter().enumerate() { + assert!( + memory + .config + .get() + .address_range + .start() + .0 + .is_multiple_of(BUS_WIDTH as u64) + ); + assert!( + memory + .config + .get() + .address_range + .last() + .wrapping_add(1) + .is_multiple_of(BUS_WIDTH as u64) + ); + if i == 0 { + for log2_read_size in 0..=LOG2_BUS_WIDTH { + let read_size = 1 << log2_read_size; + for offset in (0..BUS_WIDTH).step_by(read_size) { + sequence.push(Op { + addr: memory.config.get().address_range.start().0, + read_mask: std::array::from_fn(|byte_index| { + byte_index + .checked_sub(offset) + .is_some_and(|v| v < read_size) + }), + }); + } + } + } + for (addr, chunk) in (memory.config.get().address_range.start().0..) + .step_by(BUS_WIDTH) + .zip(memory.contents.as_bytes().chunks(BUS_WIDTH)) + { + let mut op = Op { + addr, + read_mask: [true; BUS_WIDTH], + }; + op.read_mask[chunk.len()..].fill(false); + if sequence.last() != Some(&op) { + sequence.push(op); + } + } + } + sim.fork_join_scope(async |scope, mut sim| { + scope.spawn_detached(async |_scope, mut sim| { + sim.resettable( + cd, + async |mut sim| { + sim.write( + output_interface.start.data, + #[hdl(sim)] + (output_interface.ty().start.data).HdlNone(), + ) + .await; + }, + |sim, ()| { + generator( + cd, + output_interface, + config, + &sequence, + &generator_delay_sequence_index, + sim, + ) + }, + ) + .await + }); + sim.resettable( + cd, + async |mut sim| { + sim.write_bool(finished, false).await; + sim.write_bool(output_interface.finish.ready, false).await; + }, + async |mut sim, ()| { + checker( + cd, + output_interface, + config, + &sequence, + memories, + &checker_delay_sequence_index, + &mut sim, + ) + .await; + sim.write_bool(finished, true).await; + loop { + sim.write_bool(output_interface.finish.ready, true).await; + sim.wait_for_clock_edge(cd.clk).await; + #[hdl(sim)] + if let HdlSome(finish) = + sim.read_past(output_interface.finish.data, cd.clk).await + { + panic!("spurious finished transaction: {finish:#?}"); + } + } + }, + ) + .await + }) + .await; + }, + ); +} + +#[hdl_module] +fn memory_interface_adapter_no_split_dut(memories: Interned<[Memory]>) { + #[hdl] + let cd: ClockDomain = m.input(); + #[hdl] + let finished: Bool = m.output(); + #[hdl] + let mock_cpu = instance(mock_cpu(memories)); + connect(mock_cpu.cd, cd); + connect(finished, mock_cpu.finished); + let (fields, inputs): (Vec<_>, Vec<_>) = memories + .iter() + .enumerate() + .map(|(index, &memory)| { + let mock_mem = instance_with_loc( + &format!("mock_mem_{index}"), + mock_memory(memory), + SourceLocation::caller(), + ); + connect(mock_mem.cd, cd); + ( + BundleField { + name: format!("{index}").intern_deref(), + flipped: false, + ty: MemoryInterface[memory.config].canonical(), + }, + mock_mem.input_interface, + ) + }) + .unzip(); + let bundle_ty = Bundle::new(fields.intern_deref()); + #[hdl] + let adapter = instance(memory_interface_adapter_no_split( + mock_cpu.ty().output_interface.config, + bundle_ty, + )); + connect(adapter.cd, cd); + connect(adapter.input_interface, mock_cpu.output_interface); + for (field, input) in bundle_ty.fields().into_iter().zip(inputs) { + connect(input, Expr::field(adapter.output_interfaces, &field.name)); + } +} + +#[test] +#[hdl] +fn test_memory_interface_adapter_no_split() { + let _n = SourceLocation::normalize_files_for_tests(); + let memories = vec![ + Memory::new("Testing", 3, AddressRange::from_range(0x1000..0x2000)), + Memory::new("Memory2.", 2, AddressRange::from_range(0x2000..0x2010)), + Memory::new("Contents Test", 0, AddressRange::from_range(0x3000..0x3100)), + ] + .intern_deref(); + let m = memory_interface_adapter_no_split_dut(memories); + let mut sim = Simulation::new(m); + let writer = RcWriter::default(); + sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); + struct DumpVcdOnDrop { + writer: Option, + } + impl Drop for DumpVcdOnDrop { + fn drop(&mut self) { + if let Some(mut writer) = self.writer.take() { + let vcd = String::from_utf8(writer.take()).unwrap(); + println!("####### VCD:\n{vcd}\n#######"); + } + } + } + let mut writer = DumpVcdOnDrop { + writer: Some(writer), + }; + sim.write_clock(sim.io().cd.clk, false); + sim.write_reset(sim.io().cd.rst, true); + for _cycle in 0..1000 { + sim.advance_time(SimDuration::from_nanos(500)); + sim.write_clock(sim.io().cd.clk, true); + sim.advance_time(SimDuration::from_nanos(500)); + sim.write_clock(sim.io().cd.clk, false); + sim.write_reset(sim.io().cd.rst, false); + } + sim.advance_time(SimDuration::from_nanos(500)); + assert!(sim.read_bool(sim.io().finished)); + let vcd = String::from_utf8(writer.writer.take().unwrap().take()).unwrap(); + println!("####### VCD:\n{vcd}\n#######"); + if vcd != include_str!("expected/memory_interface_adapter_no_split.vcd") { + panic!(); + } +} diff --git a/crates/cpu/tests/simple_uart.rs b/crates/cpu/tests/simple_uart.rs index d02230a..a11afe4 100644 --- a/crates/cpu/tests/simple_uart.rs +++ b/crates/cpu/tests/simple_uart.rs @@ -6,8 +6,8 @@ use cpu::{ MemoryInterface, MemoryInterfaceConfig, MemoryOperationErrorKind, MemoryOperationFinish, MemoryOperationFinishKind, MemoryOperationKind, MemoryOperationStart, simple_uart::{ - ReceiverQueueStatus, SIMPLE_UART_RECEIVE_OFFSET, SIMPLE_UART_SIZE, - SIMPLE_UART_STATUS_OFFSET, SIMPLE_UART_TRANSMIT_OFFSET, receiver, receiver_no_queue, + ReceiverQueueStatus, SIMPLE_UART_RECEIVE_OFFSET, SIMPLE_UART_STATUS_OFFSET, + SIMPLE_UART_TRANSMIT_OFFSET, SIMPLE_UART_USED_SIZE, receiver, receiver_no_queue, simple_uart, simple_uart_memory_interface_config, transmitter, uart_clock_gen, }, }, @@ -920,10 +920,10 @@ fn test_simple_uart() { for i in 0..2 * BUS_WIDTH_IN_BYTES as u64 { mem_op_runner - .read_bytes::<1>(SIMPLE_UART_SIZE.get() + i, 1) + .read_bytes::<1>(SIMPLE_UART_USED_SIZE.get() + i, 1) .unwrap_err(); mem_op_runner - .write_bytes(SIMPLE_UART_SIZE.get() + i, [0], 1) + .write_bytes(SIMPLE_UART_USED_SIZE.get() + i, [0], 1) .unwrap_err(); }