use rust_hdl::prelude::*; use std::fs::File; struct SignalLister {} impl VerilogVisitor for SignalLister { fn visit_signal(&mut self, s: &str) { println!("Signal: {}", s); } } #[test] fn test_write_modules_nested_ports() { #[derive(Clone, Debug, Default, LogicInterface)] struct MyBus { pub data: FIFORead<8>, pub cmd: FIFORead<3>, } #[derive(Clone, Debug, Default, LogicInterface)] struct FIFORead { pub read: Signal, pub output: Signal>, pub empty: Signal, pub almost_empty: Signal, pub underflow: Signal, } #[derive(Clone, Debug, Default, LogicBlock)] struct Widget { pub clock: Signal, pub bus: MyBus, } impl Logic for Widget { fn update(&mut self) {} fn connect(&mut self) { self.bus.data.almost_empty.connect(); self.bus.data.empty.connect(); self.bus.data.underflow.connect(); self.bus.data.output.connect(); self.bus.cmd.almost_empty.connect(); self.bus.cmd.empty.connect(); self.bus.cmd.underflow.connect(); self.bus.cmd.output.connect(); } } #[derive(Clone, Debug, Default, LogicBlock)] struct UUT { pub bus: MyBus, widget_a: Widget, widget_b: Widget, pub clock: Signal, pub select: Signal, } impl Logic for UUT { #[hdl_gen] fn update(&mut self) { self.widget_a.clock.next = self.clock.val(); self.widget_b.clock.next = self.clock.val(); if self.select.val() { self.bus.cmd.underflow.next = self.widget_a.bus.cmd.underflow.val(); self.bus.cmd.almost_empty.next = self.widget_a.bus.cmd.almost_empty.val(); self.bus.cmd.empty.next = self.widget_a.bus.cmd.empty.val(); self.bus.cmd.output.next = self.widget_a.bus.cmd.output.val() + 1; self.widget_a.bus.cmd.read.next = self.bus.cmd.read.val(); self.bus.data.underflow.next = self.widget_a.bus.data.underflow.val(); self.bus.data.almost_empty.next = self.widget_a.bus.data.almost_empty.val(); self.bus.data.empty.next = self.widget_a.bus.data.empty.val(); self.bus.data.output.next = self.widget_a.bus.data.output.val(); self.widget_a.bus.data.read.next = self.bus.data.read.val(); } else { self.bus.cmd.underflow.next = self.widget_b.bus.cmd.underflow.val(); self.bus.cmd.almost_empty.next = self.widget_b.bus.cmd.almost_empty.val(); self.bus.cmd.empty.next = self.widget_b.bus.cmd.empty.val(); self.bus.cmd.output.next = self.widget_b.bus.cmd.output.val(); self.widget_b.bus.cmd.read.next = self.bus.cmd.read.val(); self.bus.data.underflow.next = self.widget_b.bus.data.underflow.val(); self.bus.data.almost_empty.next = self.widget_b.bus.data.almost_empty.val(); self.bus.data.empty.next = self.widget_b.bus.data.empty.val(); self.bus.data.output.next = self.widget_b.bus.data.output.val(); self.widget_b.bus.data.read.next = self.bus.data.read.val(); } } } let mut uut = UUT::default(); uut.connect_all(); check_all(&uut).unwrap(); let mut defines = ModuleDefines::default(); uut.accept("uut", &mut defines); defines.defines(); let code = uut.hdl(); let mut sig = SignalLister {}; if let rust_hdl::core::ast::Verilog::Combinatorial(q) = code { sig.visit_block(&q); } let mut jnk = File::create(vcd_path!("test.vcd")).unwrap(); let dev = write_vcd_header(&mut jnk, &uut); let _dev = write_vcd_dump(dev, &uut); }