Install
openclaw skills install @billchen1020/verilog-designDesign, implement, and verify Verilog/SystemVerilog modules with spec-driven development, self-checking testbenches, and automated simulation workflows. Supports Synopsys VCS, Cadence Xrun, Icarus Verilog simulators, and slang static syntax checker. Use when the user needs to write Verilog modules, design digital circuits, create counters/FSMs/interfaces, simulate and verify designs, or analyze VCD waveforms.
openclaw skills install @billchen1020/verilog-designalways @(posedge clk) for sequential logicassign or always @(*) for combinational logicBefore simulation, run static syntax checking using slang:
# Check Verilog/SystemVerilog syntax
slang <module_name>.v
# Or for SystemVerilog files
slang <module_name>.sv
What slang checks:
If slang reports errors:
Before simulation, verify:
if/case branches assign in combinational blocks)default case branch=) in sequential always blocks<=) in combinational always blockstimescale directive present in all source filesalways #5 clk = ~clk; for 10ns period)$display() or $monitor() for pass/fail reporting$finish() after all tests complete<module_name>_tb.vThe skill automatically detects and uses available simulators in priority order:
vcs command available)xrun command available)# Priority order: VCS → Xrun → Icarus
which vcs && use_vcs
which xrun && use_xrun
fallback to iverilog
vcs -full64 -debug_acc+all -l sim.log -R <module_name>.v <module_name>_tb.v
vcs -full64 -debug_acc+all -sverilog -l sim.log -R <module_name>.sv <module_name>_tb.sv
xrun -64bit -access rwc -l sim.log <module_name>.v <module_name>_tb.v
xrun -64bit -access rwc -sv -l sim.log -R <module_name>.sv <module_name>_tb.sv
iverilog -o <module_name>.vvp <module_name>.v <module_name>_tb.v
vvp <module_name>.vvp
⚠️ Important: Always use VCD format for waveform dumping to ensure compatibility:
initial begin
$dumpfile("<module_name>.vcd");
$dumpvars(0, <module_name>_tb);
end
$dumpfile()/$dumpvars()gtkwave ORpython3 <skill_dir>/scripts/check_vcd.py <module>.vcd`timescale 1ns/1ps
module <module>_tb;
// Parameters
parameter CLK_PERIOD = 10;
// Signals
reg clk;
reg rst_n;
// ... add inputs/outputs
// Instantiate DUT
<module> dut (
.clk(clk),
.rst_n(rst_n),
// ... ports
);
// Clock generation
initial begin
clk = 0;
forever #(CLK_PERIOD/2) clk = ~clk;
end
// VCD dump
initial begin
$dumpfile("<module>.vcd");
$dumpvars(0, <module>_tb);
end
// Test stimulus
initial begin
// Initialize
rst_n = 0;
// ... init inputs
// Release reset
#(CLK_PERIOD * 2);
rst_n = 1;
// Apply test vectors
// ... stimulus code
// Check results
// ... self-checking assertions
#(CLK_PERIOD * 10);
$finish();
end
// Monitor
initial begin
$monitor("Time=%0t: signals=...", $time);
end
endmodule
For automated waveform checking, use Python VCD parsing. Reference: references/vcd-analysis.md
memory/verilog_specs/<module_name>_spec.md<module_name>.v<module_name>_tb.v.vvp (Icarus), sim.log, and .vcd filesUse the provided helper script to automatically select and run the best available simulator:
# The script checks for VCS → Xrun → Icarus in order
bash <skill_dir>/scripts/simulate.sh <module_name>
Example workflow:
# 1. Detect simulator and run
bash scripts/simulate.sh counter
# 2. Check simulation log
cat sim.log
# 3. Analyze VCD waveforms
python3 scripts/check_vcd.py counter.vcd
| Tool | Command | Purpose |
|---|---|---|
| Synopsys VCS | vcs -full64 -debug_acc+all -l sim.log -R file.v | Compile & Simulate Verilog |
| Synopsys VCS (SV) | vcs -full64 -debug_acc+all -sverilog -l sim.log -R file.sv | Compile & Simulate SystemVerilog |
| Cadence Xrun | xrun -64bit -access rwc -l sim.log file.v | Compile & Simulate Verilog |
| Cadence Xrun (SV) | xrun -64bit -access rwc -sv -l sim.log -R file.sv | Compile & Simulate SystemVerilog |
| Icarus Verilog | iverilog -o out.vvp file.v | Compile Verilog (fallback) |
| VVP | vvp out.vvp | Run simulation |
| GTKWave | gtkwave dump.vcd | View waveforms (optional) |
| Issue | Fix |
|---|---|
| Multiple drivers | Ensure one-always-one-signal: each signal assigned in exactly one always block |
| Latch inference | Ensure all if/case branches assign in combinational always |
| Missing reset | Include explicit reset in sequential always blocks |
| Race conditions | Use non-blocking <= in sequential logic only |
| Simulation mismatch | Check timescale and delays |
| VCD not generated | Ensure $dumpfile() called before $dumpvars() |
| Symptom | Cause | Solution |
|---|---|---|
| No output, simulation stuck | Combinational loop | Check for circular logic in combinational always blocks |
| Infinite loop warning | Zero-delay feedback | Add delay elements or check async feedback paths |
| Division by zero | Runtime calculation error | Check divisor is never zero |
| Array out of bounds | Invalid index | Verify index range before array access |
| Symptom | Cause | Solution |
|---|---|---|
| Specific signal is X | Uninitialized register | Add explicit reset value |
| Wide bus partially X | Mixed width assignment | Check vector width consistency |
| After reset release | Reset deassertion timing | Ensure reset held long enough |
| Random X propagation | X propagation from input | Trace back to source of X |
| Symptom | Cause | Solution |
|---|---|---|
| Output one cycle late | Blocking vs non-blocking | Use <= in sequential always blocks |
| Glitches on output | Combinational logic hazard | Add register stage or use synchronous output |
| Setup/hold violations (ASIC) | Clock/data skew | Check synthesis timing reports |
| Error | Cause | Solution |
|---|---|---|
| "Not synthesizable" | Unsupported Verilog construct | Replace with synthesizable equivalent |
| "Multiple drivers" | Signal assigned in multiple always | Merge logic or use intermediate signals |
| "Latch inferred" | Incomplete if/case in combinational | Add default assignment or use else |
| "Undriven signal" | Output declared but not assigned | Connect to logic or tie to constant |
Every Verilog file should include:
/**
* Module: <module_name>
* Description: <brief description>
* Author: <name>
* Date: <YYYY-MM-DD>
* Version: <major>.<minor>.<patch>
*
* Changelog:
* v1.0.0 - <date> - Initial release
* v1.1.0 - <date> - <description of changes>
* v2.0.0 - <date> - <breaking changes>
*
* Parameters:
* - PARAM1: <description> (default: <value>)
* - PARAM2: <description> (default: <value>)
*
* Ports:
* - clk: <description>
* - rst_n: <description>
* ...
*/
# Before starting new feature
git checkout -b feature/new-functionality
# After completing and testing
git add <files>
git commit -m "feat: add <feature> to <module>"
git checkout main
git merge feature/new-functionality