# Mixed-language logging This runnable example combines C++ testbench messages with diagnostics authored inside the RTL. Both enter the same sink and optional `LogHistory`, receive one per-test sequence, and retain their source language and source location. ```sh make cpp-dpi-mixed-logging-run make cpp-dpi-mixed-logging-output-test make cpp-dpi-mixed-logging-sv-run ``` `cpptb build` adds the SV package, DPI bridge, include path, and `CPPTB_ENABLE_SV_LOGGING` define automatically. Users author only the testbench and the guarded logging calls.
C++ testbench
```cpp Task mixed_language_logging(Dut dut, TestContext& test) { auto log = test.logger("cpp.driver"); log.info("starting mixed-language traffic"); dut.clk.set_now(0); test.start_clock(dut.clk, 10_ns); dut.rst_n.set(0); dut.valid.set(0); dut.data.set(0); co_await clock_cycles(dut.clk, 2); dut.rst_n.set(1); for (uint32_t index = 0; index < 2; ++index) { co_await RisingEdge{dut.clk}; dut.data.set(0x1234'0000u + index); dut.valid.set(1); co_await RisingEdge{dut.clk}; co_await ReadOnly{}; test.expect_eq("accepted count", dut.accepted_count.get(), index + 1); log.info([&] { return "observed accepted count=" + std::to_string(index + 1); }); co_await NextTimeStep{}; dut.valid.set(0); } } ```
Instrumented SystemVerilog
```systemverilog `ifdef CPPTB_ENABLE_SV_LOGGING `include "cpptb/sv/cpptb_log.svh" `endif always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin accepted_count <= '0; end else if (valid) begin accepted_count <= accepted_count + 1'b1; `ifdef CPPTB_ENABLE_SV_LOGGING `cpptb_info($sformatf("accepted data=0x%08x", data), "request_monitor") `endif end end ``` The output checker asserts that all five records have contiguous sequence numbers, the two RTL records have `SystemVerilog` origin plus file, line, scope, and hierarchy metadata, and the three C++ records retain C++ source locations. The standalone pure-SV twin drives the same two transfers and checks the same counter results. See [Structured logging](../logging.md#systemverilog-messages) for filtering, origin semantics, custom sinks, and the distinction from ordinary `$display`.