rust_sfq 1.0.4

DSL for designing SFQ circuits in Rust.
Documentation
use super::port_declarations;
use crate::testbench::{Testbench, TestbenchBackend};

pub struct LogicalVerilogTestbench;

impl TestbenchBackend for LogicalVerilogTestbench {
    fn generate(&self, testbench: &Testbench<'_>) -> String {
        let tb = testbench.normalize();
        let (inputs, outputs) = port_declarations(&tb);
        let mut res = Vec::new();

        res.push("`timescale 1ps / 100fs".to_string());
        res.push("`include \"all.v\"".to_string());
        res.push("`include \"modules.v\"".to_string());
        res.push(String::new());
        res.push("module top;".to_string());
        res.push("  // Inputs".to_string());
        if !inputs.is_empty() {
            res.push(format!("  reg {};", inputs.join(", ")));
        }
        res.push("  // Outputs".to_string());
        if !outputs.is_empty() {
            res.push(format!("  wire {};", outputs.join(", ")));
        }
        res.push(String::new());
        res.push("  reg __cycle;".to_string());
        res.push("  integer step;".to_string());
        res.push(String::new());
        res.push(format!("  {} dut (.*);", tb.circuit.name()));
        res.push(String::new());
        res.push("  // Simulation Steps".to_string());
        res.push("  initial begin".to_string());
        res.push("    __cycle = 0;".to_string());
        res.push("    step = 0;".to_string());
        res.push("    forever begin".to_string());
        res.push("      #50;".to_string());
        res.push("      __cycle = 0;".to_string());
        res.push("      #50;".to_string());
        res.push("      __cycle = 1;".to_string());
        res.push("      step = step + 1;".to_string());
        res.push("    end".to_string());
        res.push("  end".to_string());
        res.push(String::new());
        res.push("  // Input patterns".to_string());
        res.push("  initial begin".to_string());
        for signal in &tb.signals {
            res.push(format!("    {} = {};", signal.name, signal.values[0]));
        }
        for cycle in 1..tb.cycles {
            res.push("    @(posedge __cycle);".to_string());
            for signal in &tb.signals {
                res.push(format!("    {} <= {};", signal.name, signal.values[cycle]));
            }
        }
        res.push("    @(posedge __cycle);".to_string());
        res.push("    $finish;".to_string());
        res.push("  end".to_string());
        res.push(String::new());
        res.push("  initial begin".to_string());
        res.push(format!("    $dumpfile(\"{}.vcd\");", tb.name));
        res.push("    $dumpvars(0, top);".to_string());
        res.push("  end".to_string());
        res.push("endmodule".to_string());

        res.join("\n")
    }
}