diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 5d37baf..d2906e1 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -42,12 +42,8 @@ use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; use hashbrown::{HashMap, HashSet}; use num_bigint::BigInt; use num_traits::{Signed, ToPrimitive, Zero}; -use petgraph::{ - data::FromElements, - visit::{ - EdgeRef, GraphBase, IntoEdgeReferences, IntoNeighbors, IntoNeighborsDirected, - IntoNodeIdentifiers, IntoNodeReferences, NodeRef, VisitMap, Visitable, - }, +use petgraph::visit::{ + GraphBase, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers, VisitMap, Visitable, }; use std::{borrow::Cow, collections::BTreeSet, fmt, marker::PhantomData, mem, ops::IndexMut}; @@ -388,8 +384,8 @@ impl CompiledExpr { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] enum AssignmentOrSlotIndex { AssignmentIndex(usize), - SmallSlot(StatePartIndex), - BigSlot(StatePartIndex), + SmallSlots(StatePartIndex), + BigSlots(StatePartIndex), } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -412,15 +408,6 @@ enum AssignmentIO { }, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -enum AssignmentsEdge { - IO(AssignmentIO), - AssignmentImmediatePredecessor { - predecessor_assignment_index: usize, - assignment_index: usize, - }, -} - #[derive(Debug)] enum Assignments { Accumulating { @@ -428,7 +415,6 @@ enum Assignments { }, Finalized { assignments: Box<[Assignment]>, - slots_layout: TypeLayout, slot_readers: SlotToAssignmentIndexFullMap, slot_writers: SlotToAssignmentIndexFullMap, assignment_immediate_predecessors: Box<[Box<[usize]>]>, @@ -445,13 +431,13 @@ impl Default for Assignments { } impl Assignments { - fn finalize(&mut self, slots_layout: TypeLayout) { + fn finalize(&mut self, slots_len: TypeLen) { let Self::Accumulating { assignments } = self else { unreachable!("already finalized"); }; let assignments = mem::take(assignments).into_boxed_slice(); - let mut slot_readers = SlotToAssignmentIndexFullMap::new(slots_layout.len()); - let mut slot_writers = SlotToAssignmentIndexFullMap::new(slots_layout.len()); + let mut slot_readers = SlotToAssignmentIndexFullMap::new(slots_len); + let mut slot_writers = SlotToAssignmentIndexFullMap::new(slots_len); let mut assignment_immediate_predecessors = vec![BTreeSet::new(); assignments.len()]; let mut assignment_immediate_successors = vec![BTreeSet::new(); assignments.len()]; for (assignment_index, assignment) in assignments.iter().enumerate() { @@ -479,7 +465,6 @@ impl Assignments { } *self = Self::Finalized { assignments, - slots_layout, slot_readers, slot_writers, assignment_immediate_predecessors: assignment_immediate_predecessors @@ -504,12 +489,6 @@ impl Assignments { }; assignments } - fn slots_layout(&self) -> TypeLayout { - let Self::Finalized { slots_layout, .. } = self else { - unreachable!("Assignments::finalize should have been called"); - }; - *slots_layout - } fn slot_readers(&self) -> &SlotToAssignmentIndexFullMap { let Self::Finalized { slot_readers, .. } = self else { unreachable!("Assignments::finalize should have been called"); @@ -542,131 +521,46 @@ impl Assignments { }; assignment_immediate_successors } - fn elements(&self) -> AssignmentsElements<'_> { - let SlotToAssignmentIndexFullMap(TypeParts { - small_slots, - big_slots, - }) = self.slot_readers(); - AssignmentsElements { - node_indexes: HashMap::with_capacity( - self.assignments().len() + small_slots.len() + big_slots.len(), - ), - nodes: self.node_references(), - edges: self.edge_references(), - } - } } impl GraphBase for Assignments { - type EdgeId = AssignmentsEdge; + type EdgeId = AssignmentIO; type NodeId = AssignmentOrSlotIndex; } -#[derive(Debug, Clone, Copy)] -enum AssignmentsNodeRef<'a> { - Assignment { - index: usize, - assignment: &'a Assignment, - }, - SmallSlot(StatePartIndex, SlotDebugData), - BigSlot(StatePartIndex, SlotDebugData), -} - -impl<'a> NodeRef for AssignmentsNodeRef<'a> { - type NodeId = AssignmentOrSlotIndex; - type Weight = AssignmentsNodeRef<'a>; - - fn id(&self) -> Self::NodeId { - match *self { - AssignmentsNodeRef::Assignment { - index, - assignment: _, - } => AssignmentOrSlotIndex::AssignmentIndex(index), - AssignmentsNodeRef::SmallSlot(slot, _) => AssignmentOrSlotIndex::SmallSlot(slot), - AssignmentsNodeRef::BigSlot(slot, _) => AssignmentOrSlotIndex::BigSlot(slot), - } - } - - fn weight(&self) -> &Self::Weight { - self - } -} - -impl<'a> petgraph::visit::Data for &'a Assignments { - type NodeWeight = AssignmentsNodeRef<'a>; - type EdgeWeight = AssignmentsEdge; -} - -struct AssignmentsElements<'a> { - node_indexes: HashMap, - nodes: AssignmentsNodes<'a>, - edges: AssignmentsEdges<'a>, -} - -impl<'a> Iterator for AssignmentsElements<'a> { - type Item = petgraph::data::Element< - <&'a Assignments as petgraph::visit::Data>::NodeWeight, - <&'a Assignments as petgraph::visit::Data>::EdgeWeight, - >; - - fn next(&mut self) -> Option { - let Self { - node_indexes, - nodes, - edges, - } = self; - if let Some(node) = nodes.next() { - node_indexes.insert(node.id(), node_indexes.len()); - return Some(petgraph::data::Element::Node { weight: node }); - } - let edge = edges.next()?; - Some(petgraph::data::Element::Edge { - source: node_indexes[&edge.source()], - target: node_indexes[&edge.target()], - weight: *edge.weight(), - }) - } -} - -#[derive(Clone)] struct AssignmentsNodeIdentifiers { assignment_indexes: std::ops::Range, small_slots: std::ops::Range, big_slots: std::ops::Range, } -impl AssignmentsNodeIdentifiers { - fn internal_iter<'a>(&'a mut self) -> impl Iterator + 'a { +impl Iterator for AssignmentsNodeIdentifiers { + type Item = AssignmentOrSlotIndex; + fn next(&mut self) -> Option { let Self { assignment_indexes, small_slots, big_slots, } = self; assignment_indexes + .next() .map(AssignmentOrSlotIndex::AssignmentIndex) - .chain(small_slots.map(|value| { - AssignmentOrSlotIndex::SmallSlot(StatePartIndex { - value, - _phantom: PhantomData, + .or_else(|| { + small_slots.next().map(|value| { + AssignmentOrSlotIndex::SmallSlots(StatePartIndex { + value, + _phantom: PhantomData, + }) }) - })) - .chain(big_slots.map(|value| { - AssignmentOrSlotIndex::BigSlot(StatePartIndex { - value, - _phantom: PhantomData, + }) + .or_else(|| { + big_slots.next().map(|value| { + AssignmentOrSlotIndex::BigSlots(StatePartIndex { + value, + _phantom: PhantomData, + }) }) - })) - } -} - -impl Iterator for AssignmentsNodeIdentifiers { - type Item = AssignmentOrSlotIndex; - fn next(&mut self) -> Option { - self.internal_iter().next() - } - - fn nth(&mut self, n: usize) -> Option { - self.internal_iter().nth(n) + }) } } @@ -686,44 +580,6 @@ impl<'a> IntoNodeIdentifiers for &'a Assignments { } } -struct AssignmentsNodes<'a> { - assignments: &'a Assignments, - nodes: AssignmentsNodeIdentifiers, -} - -impl<'a> Iterator for AssignmentsNodes<'a> { - type Item = AssignmentsNodeRef<'a>; - - fn next(&mut self) -> Option { - self.nodes.next().map(|node| match node { - AssignmentOrSlotIndex::AssignmentIndex(index) => AssignmentsNodeRef::Assignment { - index, - assignment: &self.assignments.assignments()[index], - }, - AssignmentOrSlotIndex::SmallSlot(slot) => AssignmentsNodeRef::SmallSlot( - slot, - *self.assignments.slots_layout().small_slots.debug_data(slot), - ), - AssignmentOrSlotIndex::BigSlot(slot) => AssignmentsNodeRef::BigSlot( - slot, - *self.assignments.slots_layout().big_slots.debug_data(slot), - ), - }) - } -} - -impl<'a> IntoNodeReferences for &'a Assignments { - type NodeRef = AssignmentsNodeRef<'a>; - type NodeReferences = AssignmentsNodes<'a>; - - fn node_references(self) -> Self::NodeReferences { - AssignmentsNodes { - assignments: self, - nodes: self.node_identifiers(), - } - } -} - struct AssignmentsNeighborsDirected<'a> { assignment_indexes: std::slice::Iter<'a, usize>, small_slots: std::collections::btree_set::Iter<'a, StatePartIndex>, @@ -747,13 +603,13 @@ impl Iterator for AssignmentsNeighborsDirected<'_> { } else if let retval @ Some(_) = small_slots .next() .copied() - .map(AssignmentOrSlotIndex::SmallSlot) + .map(AssignmentOrSlotIndex::SmallSlots) { retval } else if let retval @ Some(_) = big_slots .next() .copied() - .map(AssignmentOrSlotIndex::BigSlot) + .map(AssignmentOrSlotIndex::BigSlots) { retval } else { @@ -808,12 +664,12 @@ impl<'a> IntoNeighborsDirected for &'a Assignments { big_slots: big_slots.iter(), } } - AssignmentOrSlotIndex::SmallSlot(slot) => AssignmentsNeighborsDirected { + AssignmentOrSlotIndex::SmallSlots(slot) => AssignmentsNeighborsDirected { assignment_indexes: slot_map[slot].iter(), small_slots: Default::default(), big_slots: Default::default(), }, - AssignmentOrSlotIndex::BigSlot(slot) => AssignmentsNeighborsDirected { + AssignmentOrSlotIndex::BigSlots(slot) => AssignmentsNeighborsDirected { assignment_indexes: slot_map[slot].iter(), small_slots: Default::default(), big_slots: Default::default(), @@ -822,149 +678,6 @@ impl<'a> IntoNeighborsDirected for &'a Assignments { } } -impl EdgeRef for AssignmentsEdge { - type NodeId = AssignmentOrSlotIndex; - type EdgeId = AssignmentsEdge; - type Weight = AssignmentsEdge; - - fn source(&self) -> Self::NodeId { - match *self { - AssignmentsEdge::IO(AssignmentIO::BigInput { - assignment_index: _, - slot, - }) => AssignmentOrSlotIndex::BigSlot(slot), - AssignmentsEdge::IO(AssignmentIO::SmallInput { - assignment_index: _, - slot, - }) => AssignmentOrSlotIndex::SmallSlot(slot), - AssignmentsEdge::IO(AssignmentIO::BigOutput { - assignment_index, - slot: _, - }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - AssignmentsEdge::IO(AssignmentIO::SmallOutput { - assignment_index, - slot: _, - }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - AssignmentsEdge::AssignmentImmediatePredecessor { - predecessor_assignment_index, - assignment_index: _, - } => AssignmentOrSlotIndex::AssignmentIndex(predecessor_assignment_index), - } - } - - fn target(&self) -> Self::NodeId { - match *self { - AssignmentsEdge::IO(AssignmentIO::BigInput { - assignment_index, - slot: _, - }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - AssignmentsEdge::IO(AssignmentIO::SmallInput { - assignment_index, - slot: _, - }) => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - AssignmentsEdge::IO(AssignmentIO::BigOutput { - assignment_index: _, - slot, - }) => AssignmentOrSlotIndex::BigSlot(slot), - AssignmentsEdge::IO(AssignmentIO::SmallOutput { - assignment_index: _, - slot, - }) => AssignmentOrSlotIndex::SmallSlot(slot), - AssignmentsEdge::AssignmentImmediatePredecessor { - predecessor_assignment_index: _, - assignment_index, - } => AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - } - } - - fn weight(&self) -> &Self::Weight { - self - } - - fn id(&self) -> Self::EdgeId { - *self - } -} - -struct AssignmentsEdges<'a> { - assignments: &'a Assignments, - nodes: AssignmentsNodeIdentifiers, - outgoing_neighbors: Option<(AssignmentOrSlotIndex, AssignmentsNeighborsDirected<'a>)>, -} - -impl Iterator for AssignmentsEdges<'_> { - type Item = AssignmentsEdge; - - fn next(&mut self) -> Option { - loop { - if let Some((node, outgoing_neighbors)) = &mut self.outgoing_neighbors { - if let Some(outgoing_neighbor) = outgoing_neighbors.next() { - return Some(match (*node, outgoing_neighbor) { - ( - AssignmentOrSlotIndex::SmallSlot(_) | AssignmentOrSlotIndex::BigSlot(_), - AssignmentOrSlotIndex::SmallSlot(_) | AssignmentOrSlotIndex::BigSlot(_), - ) => unreachable!(), - ( - AssignmentOrSlotIndex::AssignmentIndex(predecessor_assignment_index), - AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - ) => AssignmentsEdge::AssignmentImmediatePredecessor { - predecessor_assignment_index, - assignment_index, - }, - ( - AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - AssignmentOrSlotIndex::SmallSlot(slot), - ) => AssignmentsEdge::IO(AssignmentIO::SmallOutput { - assignment_index, - slot, - }), - ( - AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - AssignmentOrSlotIndex::BigSlot(slot), - ) => AssignmentsEdge::IO(AssignmentIO::BigOutput { - assignment_index, - slot, - }), - ( - AssignmentOrSlotIndex::SmallSlot(slot), - AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - ) => AssignmentsEdge::IO(AssignmentIO::SmallInput { - assignment_index, - slot, - }), - ( - AssignmentOrSlotIndex::BigSlot(slot), - AssignmentOrSlotIndex::AssignmentIndex(assignment_index), - ) => AssignmentsEdge::IO(AssignmentIO::BigInput { - assignment_index, - slot, - }), - }); - } - } - let node = self.nodes.next()?; - self.outgoing_neighbors = Some(( - node, - self.assignments - .neighbors_directed(node, petgraph::Direction::Outgoing), - )); - } - } -} - -impl<'a> IntoEdgeReferences for &'a Assignments { - type EdgeRef = AssignmentsEdge; - type EdgeReferences = AssignmentsEdges<'a>; - - fn edge_references(self) -> Self::EdgeReferences { - AssignmentsEdges { - assignments: self, - nodes: self.node_identifiers(), - outgoing_neighbors: None, - } - } -} - struct AssignmentsVisitMap { assignments: Vec, slots: DenseSlotSet, @@ -976,8 +689,8 @@ impl VisitMap for AssignmentsVisitMap { AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { !mem::replace(&mut self.assignments[assignment_index], true) } - AssignmentOrSlotIndex::SmallSlot(slot) => self.slots.insert(slot), - AssignmentOrSlotIndex::BigSlot(slot) => self.slots.insert(slot), + AssignmentOrSlotIndex::SmallSlots(slot) => self.slots.insert(slot), + AssignmentOrSlotIndex::BigSlots(slot) => self.slots.insert(slot), } } @@ -986,8 +699,8 @@ impl VisitMap for AssignmentsVisitMap { AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => { self.assignments[assignment_index] } - AssignmentOrSlotIndex::SmallSlot(slot) => self.slots.contains(slot), - AssignmentOrSlotIndex::BigSlot(slot) => self.slots.contains(slot), + AssignmentOrSlotIndex::SmallSlots(slot) => self.slots.contains(slot), + AssignmentOrSlotIndex::BigSlots(slot) => self.slots.contains(slot), } } } @@ -3012,15 +2725,12 @@ impl Compiler { .compile_expr(instantiated_module, Expr::canonical(expr.base())) .map_ty(Bundle::from_canonical) .field_by_index(expr.field_index()), - ExprEnum::VariantAccess(variant_access) => { - let start = Expr::ty(variant_access.base()).discriminant_bit_width(); - let len = Expr::ty(expr).bit_width(); - self.compile_expr( - instantiated_module, - variant_access.base().cast_to_bits()[start..start + len] - .cast_bits_to(Expr::ty(expr)), - ) - } + ExprEnum::VariantAccess(variant_access) => self.compile_expr( + instantiated_module, + variant_access.base().cast_to_bits() + [Expr::ty(variant_access.base()).discriminant_bit_width()..] + .cast_bits_to(Expr::ty(expr)), + ), ExprEnum::ArrayIndex(expr) => self .compile_expr(instantiated_module, Expr::canonical(expr.base())) .map_ty(Array::from_canonical) @@ -4436,13 +4146,7 @@ impl Compiler { } fn process_assignments(&mut self) { self.assignments - .finalize(self.insns.state_layout().ty.clone().into()); - println!( - "{:#?}", - petgraph::dot::Dot::new(&petgraph::graph::DiGraph::<_, _, usize>::from_elements( - self.assignments.elements() - )) - ); + .finalize(self.insns.state_layout().len().ty); let assignments_order: Vec<_> = match petgraph::algo::toposort(&self.assignments, None) { Ok(nodes) => nodes .into_iter() @@ -4456,11 +4160,11 @@ impl Compiler { "combinatorial logic cycle detected at: {}", self.assignments.assignments()[assignment_index].source_location, ), - AssignmentOrSlotIndex::SmallSlot(slot) => panic!( + AssignmentOrSlotIndex::SmallSlots(slot) => panic!( "combinatorial logic cycle detected through: {}", self.insns.state_layout().ty.small_slots.debug_data[slot.as_usize()].name, ), - AssignmentOrSlotIndex::BigSlot(slot) => panic!( + AssignmentOrSlotIndex::BigSlots(slot) => panic!( "combinatorial logic cycle detected through: {}", self.insns.state_layout().ty.big_slots.debug_data[slot.as_usize()].name, ), diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index aabf6e2..23d1275 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -1652,9 +1652,6 @@ impl StatePartLayout { _phantom: PhantomData, } } - pub(crate) fn debug_data(&self, index: StatePartIndex) -> &K::DebugData { - &self.debug_data[index.as_usize()] - } } impl From> diff --git a/crates/fayalite/src/sim/vcd.rs b/crates/fayalite/src/sim/vcd.rs index 0779b5c..8b5a58c 100644 --- a/crates/fayalite/src/sim/vcd.rs +++ b/crates/fayalite/src/sim/vcd.rs @@ -235,17 +235,6 @@ fn write_escaped(writer: &mut W, value: impl Display) -> io::Resul write!(Wrapper(writer), "{value}") } -fn is_unescaped_verilog_identifier(ident: &str) -> bool { - // we only allow ascii, so we can just check bytes - let Some((&first, rest)) = ident.as_bytes().split_first() else { - return false; // empty string is not an identifier - }; - (first.is_ascii_alphabetic() || first == b'_') - && rest - .iter() - .all(|&ch| ch.is_ascii_alphanumeric() || ch == b'_' || ch == b'$') -} - fn write_vcd_var( writer: &mut W, var_type: &str, @@ -255,12 +244,7 @@ fn write_vcd_var( ) -> io::Result<()> { write!(writer, "$var {var_type} {size} ")?; write_scalar_id(writer, id)?; - writer.write_all(b" ")?; - if !is_unescaped_verilog_identifier(name) { - writer.write_all(b"\\")?; - } - write_escaped(writer, name)?; - writer.write_all(b" $end\n") + writeln!(writer, " {name} $end") } impl WriteTrace for TraceUInt { diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index db20df2..914e64f 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -293,204 +293,5 @@ fn test_shift_register() { } } -#[hdl_module(outline_generated)] -pub fn enums() { - #[hdl] - let cd: ClockDomain = m.input(); - #[hdl] - let en: Bool = m.input(); - #[hdl] - let which_in: UInt<2> = m.input(); - #[hdl] - let data_in: UInt<4> = m.input(); - #[hdl] - let which_out: UInt<2> = m.output(); - #[hdl] - let data_out: UInt<4> = m.output(); - - #[hdl] - struct MyStruct { - a: T, - b: SInt<2>, - } - - #[hdl] - enum MyEnum { - A, - B((UInt<1>, Bool)), - C(MyStruct, 2>>), - } - - #[hdl] - let the_reg = reg_builder().clock_domain(cd).reset(MyEnum.A()); - - #[hdl] - if en { - #[hdl] - if which_in.cmp_eq(0_hdl_u2) { - connect(the_reg, MyEnum.A()); - } else if which_in.cmp_eq(1_hdl_u2) { - connect(the_reg, MyEnum.B((data_in[0].cast_to_static(), data_in[1]))); - } else { - connect( - the_reg, - MyEnum.C( - #[hdl] - MyStruct { - a: #[hdl] - [data_in[0].cast_to_static(), data_in[1].cast_to_static()], - b: data_in[2..4].cast_to_static(), - }, - ), - ); - } - } - - #[hdl] - match the_reg { - MyEnum::A => { - connect(which_out, 0_hdl_u2); - connect(data_out, 0_hdl_u4); - } - MyEnum::B(v) => { - connect(which_out, 1_hdl_u2); - connect_any(data_out, v.0 | (v.1.cast_to_static::>() << 1)); - } - MyEnum::C(v) => { - connect(which_out, 2_hdl_u2); - connect_any(data_out, v.cast_to_bits()); - } - } -} - -#[cfg(todo)] // FIXME: enum lowering currently broken -#[hdl] -#[test] -fn test_enums() { - let _n = SourceLocation::normalize_files_for_tests(); - let mut sim = Simulation::new(enums()); - let mut writer = RcWriter::default(); - sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write_clock(sim.io().cd.clk, false); - sim.write_reset(sim.io().cd.rst, true); - sim.write_bool(sim.io().en, false); - sim.write_bool_or_int(sim.io().which_in, 0_hdl_u2); - sim.write_bool_or_int(sim.io().data_in, 0_hdl_u4); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, true); - sim.advance_time(SimDuration::from_nanos(100)); - sim.write_reset(sim.io().cd.rst, false); - sim.advance_time(SimDuration::from_nanos(900)); - #[derive(Debug, PartialEq, Eq)] - struct IO { - en: bool, - which_in: u8, - data_in: u8, - which_out: u8, - data_out: u8, - } - let io_cycles = [ - IO { - en: false, - which_in: 0, - data_in: 0, - which_out: 0, - data_out: 0, - }, - IO { - en: true, - which_in: 1, - data_in: 0, - which_out: 0, - data_out: 0, - }, - IO { - en: false, - which_in: 0, - data_in: 0, - which_out: 1, - data_out: 0, - }, - IO { - en: true, - which_in: 1, - data_in: 0xF, - which_out: 1, - data_out: 0, - }, - IO { - en: true, - which_in: 1, - data_in: 0xF, - which_out: 1, - data_out: 0x3, - }, - IO { - en: true, - which_in: 2, - data_in: 0xF, - which_out: 1, - data_out: 0x3, - }, - IO { - en: true, - which_in: 2, - data_in: 0xF, - which_out: 2, - data_out: 0xF, - }, - ]; - for ( - cycle, - expected @ IO { - en, - which_in, - data_in, - which_out: _, - data_out: _, - }, - ) in io_cycles.into_iter().enumerate() - { - sim.write_bool(sim.io().en, en); - sim.write_bool_or_int(sim.io().which_in, which_in.cast_to_static()); - sim.write_bool_or_int(sim.io().data_in, data_in.cast_to_static()); - let io = IO { - en, - which_in, - data_in, - which_out: sim - .read_bool_or_int(sim.io().which_out) - .to_bigint() - .try_into() - .expect("known to be in range"), - data_out: sim - .read_bool_or_int(sim.io().data_out) - .to_bigint() - .try_into() - .expect("known to be in range"), - }; - assert_eq!( - expected, - io, - "cycle: {cycle}\nvcd:\n{}", - String::from_utf8(writer.take()).unwrap(), - ); - sim.write_clock(sim.io().cd.clk, false); - sim.advance_time(SimDuration::from_micros(1)); - sim.write_clock(sim.io().cd.clk, true); - sim.advance_time(SimDuration::from_micros(1)); - } - sim.flush_traces().unwrap(); - let vcd = String::from_utf8(writer.take()).unwrap(); - println!("####### VCD:\n{vcd}\n#######"); - if vcd != include_str!("sim/expected/enums.vcd") { - panic!(); - } - let sim_debug = format!("{sim:#?}"); - println!("#######\n{sim_debug}\n#######"); - if sim_debug != include_str!("sim/expected/enums.txt") { - panic!(); - } -} - +// TODO: add tests for enums // TODO: add tests for memories diff --git a/crates/fayalite/tests/sim/expected/enums.txt b/crates/fayalite/tests/sim/expected/enums.txt deleted file mode 100644 index e69de29..0000000 diff --git a/crates/fayalite/tests/sim/expected/enums.vcd b/crates/fayalite/tests/sim/expected/enums.vcd deleted file mode 100644 index e69de29..0000000