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<const D: usize> {
pub read: Signal<In, Bit>,
pub output: Signal<Out, Bits<D>>,
pub empty: Signal<Out, Bit>,
pub almost_empty: Signal<Out, Bit>,
pub underflow: Signal<Out, Bit>,
}
#[derive(Clone, Debug, Default, LogicBlock)]
struct Widget {
pub clock: Signal<In, Clock>,
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<In, Clock>,
pub select: Signal<In, Bit>,
}
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);
}