Scripting
SHDB supports scripting for automated testing, regression suites, and complex debug scenarios.
Script Files
SHDB scripts use the .shdb extension and contain regular SHDB commands:
# test_adder.shdb - Test script for Adder16
# Setup
reset
set A = 0
set B = 0
# Test 1: Zero addition
step 1
assert Sum == 0
assert Cout == 0
print "Test 1 passed: 0 + 0 = 0"
# Test 2: Simple addition
set A = 42
set B = 17
step 1
assert Sum == 59
assert Cout == 0
print "Test 2 passed: 42 + 17 = 59"
print "All tests passed!"
Running Scripts
From Command Line
shdb myCircuit.shdl -x test_adder.shdb
From SHDB
(shdb) source test_adder.shdb
Test 1 passed: 0 + 0 = 0
Test 2 passed: 42 + 17 = 59
All tests passed!
Assertions
Basic Assertions
assert Sum == 59
assert Cout == 0
assert A > B
Assertion Messages
assert Sum == 59, "Sum should be 59, got " Sum
Soft Assertions
Continue after failure:
check Sum == 59 # Warn but don't stop
Variables
Debugger Variables
set $expected = 42 + 17
set $count = 0
set $threshold = 100
Using Variables
set A = $count
set B = $expected
assert Sum > $threshold
print "Count: " $count
Incrementing
set $count = $count + 1
Control Flow
If/Else
if Sum > 255
print "Overflow detected!"
set $overflow = 1
else
set $overflow = 0
end
if Cout == 1
print "Carry out"
elsif Sum == 0
print "Zero result"
else
print "Normal result"
end
For Loops
for $i in 1..16
set A = $i
step 1
print "A=" $i " Sum=" Sum
end
Range variations:
for $i in 0..255 # 0 to 255 inclusive
for $i in 1..16 # 1 to 16 inclusive
for $i in 0..100..2 # 0, 2, 4, ..., 100 (step 2)
While Loops
set $i = 0
while $i < 100
set A = $i
step 1
set $i = $i + 1
end
Break and Continue
for $i in 1..1000
set A = $i
step 1
if Cout == 1
print "Carry at A=" $i
break
end
end
Custom Commands
Defining Commands
define test-add
set A = $arg0
set B = $arg1
step 1
print "A=" A " B=" B " Sum=" Sum
if Sum != ($arg0 + $arg1)
print "FAIL!"
end
end
Using Custom Commands
(shdb) test-add 100 50
A=100 B=50 Sum=150
(shdb) test-add 255 1
A=255 B=1 Sum=256
Commands with Defaults
define test-value
set A = $arg0
set B = ${arg1:-0} # Default to 0
step 1
print Sum
end
Redefining Commands
define test-add
# New implementation
end
Output and Logging
Print
print "Testing with A=" A
print "Result: " Sum " (expected " $expected ")"
print # Blank line
Printf (Formatted)
printf "A=%04x B=%04x Sum=%04x\n" A B Sum
printf "Pass rate: %.2f%%\n" ($passed / $total * 100)
Logging to File
log "test_results.txt"
print "Test output goes to file"
log off
Error Handling
Try/Catch
try
set A = $value
step 1
assert Sum == $expected
catch
print "Test failed with error: " $error
set $failures = $failures + 1
end
Exit Codes
if $failures > 0
exit 1 # Non-zero exit code
end
exit 0
Practical Examples
Exhaustive Test
# exhaustive_4bit.shdb - Test all 4-bit input combinations
define test-all
set $passed = 0
set $failed = 0
for $a in 0..15
for $b in 0..15
set A = $a
set B = $b
step 1
set $expected = ($a + $b) & 0x1F # 5 bits for sum+carry
set $actual = Sum + (Cout << 4)
if $actual == $expected
set $passed = $passed + 1
else
print "FAIL: " $a "+" $b "=" $actual " expected " $expected
set $failed = $failed + 1
end
end
end
print "Passed: " $passed "/" ($passed + $failed)
if $failed > 0
exit 1
end
end
reset
test-all
Regression Suite
# regression.shdb
define run-test
source $arg0
if $result != 0
print "FAILED: " $arg0
set $failures = $failures + 1
else
print "PASSED: " $arg0
end
end
set $failures = 0
run-test "tests/basic_add.shdb"
run-test "tests/overflow.shdb"
run-test "tests/carry_chain.shdb"
run-test "tests/boundary.shdb"
print ""
print "Failures: " $failures
exit $failures
Performance Measurement
# benchmark.shdb
define benchmark
set $start = $cycle
for $i in 1..10000
set A = $i
set B = $i * 2
step 1
end
set $elapsed = $cycle - $start
print "10000 iterations in " $elapsed " cycles"
end
reset
benchmark
Test with Recording
# recorded_test.shdb
reset
record signals A B Sum Cout
record start
# Run test patterns
for $pattern in 0x0000 0x5555 0xAAAA 0xFFFF
set A = $pattern
set B = ~$pattern & 0xFFFF
step 1
end
record stop
record export pattern_test.vcd
print "Waveform saved to pattern_test.vcd"
Script Best Practices
-
Use meaningful names for custom commands and variables
-
Add comments explaining test intent
-
Use assertions for expected values
-
Print progress for long-running tests
-
Return exit codes for CI integration
-
Organize in directories:
tests/
├── unit/
│ ├── test_add.shdb
│ └── test_overflow.shdb
├── integration/
│ └── test_full_circuit.shdb
└── run_all.shdb -
Parameterize tests with custom commands
-
Record waveforms for failed tests to aid debugging