Use waveform-mcp tools to analyze VCD/FST waveforms and inspect Buckyball signal timing. Use this skill for cycle-level timing analysis, handshake debugging, FSM transition checks, or whenever waveform-level evidence is needed.
The project uses waveform-mcp with these tools:
open_waveform(file_path) - open a VCD/FST filelist_signals(waveform_id, hierarchy_prefix?, name_pattern?, recursive?) - list signalsread_signal(waveform_id, signal_path, time_index|time_indices) - read signal valuesget_signal_info(waveform_id, signal_path) - get signal metadatafind_signal_events(waveform_id, signal_path, start?, end?, limit?) - find signal transitionsfind_conditional_events(waveform_id, condition, start?, end?, limit?) - search by conditionclose_waveform(waveform_id) - close waveformWaveforms generated by simulation are usually in:
arch/log/<timestamp>/.vcd or .fstfind arch/log -name "*.vcd" -o -name "*.fst" | head -5 to locate filesTypical Buckyball signal hierarchy:
TOP
├── BuckyballToy (top)
│ ├── bbtile (BBTile)
│ │ ├── buckyball (Buckyball core)
│ │ │ ├── frontend
│ │ │ │ ├── globalDecoder
│ │ │ │ └── globalROB
│ │ │ ├── ballDomain
│ │ │ │ └── bbus (BBus)
│ │ │ │ ├── cmdRouter
│ │ │ │ ├── pmc (BallCyclePMC)
│ │ │ │ ├── balls_0 (first Ball, sorted by ballId)
│ │ │ │ ├── balls_1
│ │ │ │ └── ...
│ │ │ └── memDomain
│ │ │ ├── memFrontend
│ │ │ └── memBackend
To locate signals for a specific Ball:
list_signals(waveform_id, recursive=false) - inspect top level firsthierarchy_prefix="TOP.BuckyballToy"list_signals(waveform_id, name_pattern="relu", recursive=true)Decoupled valid/ready)Check whether cmdReq handshakes succeed:
find_conditional_events(waveform_id,
condition="TOP...cmdReq_valid && TOP...cmdReq_ready")
Check cmdResp handshakes:
find_conditional_events(waveform_id,
condition="TOP...cmdResp_valid && TOP...cmdResp_ready")
Verify 1-cycle SRAM read latency:
# Find read request events
find_conditional_events(waveform_id,
condition="TOP...bankRead_0_io_req_valid && TOP...bankRead_0_io_req_ready")
# Check `resp.valid` in the next cycle
# Use time_index + 1 from request events
read_signal(waveform_id, "TOP...bankRead_0_io_resp_valid", time_index=<req_time+1>)
Find all transitions of the state register:
find_signal_events(waveform_id, signal_path="TOP...state")
Then read values at each transition point to reconstruct state evolution.
Measure cycles from cmdReq.fire to cmdResp.fire:
# Find cmdReq handshake timestamps
req_events = find_conditional_events(waveform_id,
condition="TOP...cmdReq_valid && TOP...cmdReq_ready")
# Find cmdResp handshake timestamps
resp_events = find_conditional_events(waveform_id,
condition="TOP...cmdResp_valid && TOP...cmdResp_ready")
# Matching resp_time - req_time gives latency
Read SRAM read/write addresses and data at a specific time:
read_signal(waveform_id, "TOP...bankRead_0_io_req_bits_addr", time_index=T)
read_signal(waveform_id, "TOP...bankRead_0_io_resp_bits_data", time_index=T+1)
read_signal(waveform_id, "TOP...bankWrite_0_io_req_bits_addr", time_index=T)
read_signal(waveform_id, "TOP...bankWrite_0_io_req_bits_data", time_index=T)
find_conditional_events conditions support:
TOP.module.signal~(NOT), &(AND), |(OR), ^(XOR)&&, ||, !==, !=signal[bit] or signal[msb:lsb]$past(signal) - value at previous time_index4'b0001, 8'hFFCommon patterns:
!$past(TOP.signal) && TOP.signal$past(TOP.signal) && !TOP.signalTOP.valid && TOP.readyTOP.flags & 4'b0001