Created
March 15, 2016 13:56
-
-
Save aksiksi/c7a40d82b3deddc1c607 to your computer and use it in GitHub Desktop.
Generates a Spectre input stimulus file for n vectors. Run with --help for details and an example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
''' | |
Outputs a Cadence ADE stimulus file for n input vectors. | |
Supports Python 2.x only. I created this for use on a RHEL | |
box running Cadence. | |
Global variables | |
SOURCE: the source type generated for each bit of the vectors. | |
VDD: the value for a HIGH in your process. | |
''' | |
import sys | |
# Process voltage | |
VDD = 1.1 | |
# Clock period and input delay, in ns | |
CLOCK_PERIOD = 1e3 | |
# Voltage source definition in Spectre SPICE syntax | |
SOURCE = '%s (%s 0) vsource type=pulse val0=%.2f val1=%.2f delay=0 ' \ | |
'rise=50p fall=50p period=%.2fn width=%.2fn' | |
# Backport of bin() from 2.6 | |
# http://code.activestate.com/recipes/219300-format-integer-as-binary-string/#c7 | |
def bin(x): | |
""" | |
bin(number) -> string | |
Stringifies an int or long in base 2. | |
""" | |
if x < 0: | |
return '-' + bin(-x) | |
out = [] | |
if x == 0: | |
out.append('0') | |
while x > 0: | |
out.append('01'[x & 1]) | |
x >>= 1 | |
pass | |
try: | |
return '0b' + ''.join(reversed(out)) | |
except NameError, ne2: | |
out.reverse() | |
return '0b' + ''.join(out) | |
def exit_with_error(msg): | |
print 'ERROR: ' + msg | |
sys.exit(0) | |
def generate_stimulus_file(inputs, clock): | |
stimulus_file = [ | |
'simulator lang=spectre', | |
# Clock source | |
'_vCLK (CLK 0) vsource type=pulse val0=0 val1=1.1 delay=0 ' \ | |
'rise=50p fall=50p period=%.2fn width=%.2fn' % (clock, clock/2), | |
# Carry in source | |
'_vCin (Cin 0) vsource dc=0', | |
] | |
# Input count | |
i = 1 | |
# Loop over each input vector | |
for name, num in inputs.items(): | |
# For each number, generate one line (source) for each bit; LSB first | |
for j, bit in enumerate(reversed(num)): | |
node = r'%s\\<%d\\>' % (name, j) | |
source = '_v' + node | |
# First cycle behavior | |
if bit == '0': | |
val0, val1 = VDD, 0 | |
else: | |
val0, val1 = 0, VDD | |
period = i * clock * 2 | |
# Append line to file | |
line = SOURCE % (source, node, val0, val1, period, period/2) | |
stimulus_file.append(line) | |
i += 1 | |
return stimulus_file | |
def main(): | |
args = sys.argv[1:] | |
# Dirty command line argument parser for Python 2.4 :( | |
# NEVER DO THIS | |
# Too hurried to make it more reliable | |
if len(args) == 0 or args[0] in ['-h', '--help']: | |
print 'Cadence Spectre input stimulus file generator.' | |
print 'Takes a set of vector inputs and numbers in decimal format.' | |
print 'Example: ./stimulus.py -c 1000 -n 16 A,B 15,25' | |
print 'This will generate sources that output 15 and 25 in binary with a 1 ns clock period' | |
print 'and with 16 input sources each.' | |
print '-c and -n are OPTIONAL, but when specified, MUST be in order.' | |
sys.exit(0) | |
n = -1 | |
clock = CLOCK_PERIOD | |
# Take any optional args | |
if len(args) == 4 and args[0] == '-c': | |
clock = float(args[1]) | |
args = args[2:] | |
elif len(args) == 6 and args[2] == '-n': | |
clock = float(args[1]) | |
n = int(args[3]) | |
args = args[4:] | |
else: | |
exit_with_error('Wrong order of optional args. Run with --help for an example.') | |
try: | |
names = args[0].split(',') | |
values = args[1].split(',') | |
except: | |
exit_with_error('Wrong input format. Run with --help for an example.') | |
# Setup input dict | |
# Convert decimal number to binary string | |
try: | |
inputs = {} | |
for k, v in zip(names, values): | |
num = bin(int(v)).split('b')[1] | |
if n != -1: | |
pre = '0' * (n-len(num)) # Prepend zeroes if needed | |
inputs[k] = pre + num | |
except ValueError: | |
exit_with_error('Invalid input format. Values MUST be integers.') | |
lines = generate_stimulus_file(inputs, clock) | |
# Write stimulus file to disk | |
f = open('input_stimulus.scs', 'w') | |
f.write('\n'.join(lines) + '\n') | |
f.close() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment