diff --git a/mag/gpio_defaults_block.mag b/mag/gpio_defaults_block.mag index 4778412a..62d4b480 100644 --- a/mag/gpio_defaults_block.mag +++ b/mag/gpio_defaults_block.mag @@ -785,22 +785,6 @@ flabel metal3 s -600 3680 600 3800 0 FreeSans 480 0 0 0 gpio_defaults[8] port 13 nsew signal tristate flabel metal3 s -600 3952 600 4072 0 FreeSans 480 0 0 0 gpio_defaults[9] port 14 nsew signal tristate -rlabel metal1 1840 4352 1840 4352 0 VGND -rlabel metal1 1840 3808 1840 3808 0 VPWR -rlabel metal1 874 3162 874 3162 0 gpio_defaults_high\[10\] -rlabel metal2 683 476 683 476 0 gpio_defaults_low\[11\] -rlabel metal2 1249 476 1249 476 0 gpio_defaults_low\[12\] -rlabel metal3 659 1020 659 1020 0 gpio_defaults_low\[2\] -rlabel metal3 820 1292 820 1292 0 gpio_defaults_low\[3\] -rlabel metal1 1794 1530 1794 1530 0 gpio_defaults_low\[4\] -rlabel metal1 1104 1938 1104 1938 0 gpio_defaults_low\[5\] -rlabel metal3 820 2924 820 2924 0 gpio_defaults_low\[7\] -rlabel metal3 866 3740 866 3740 0 gpio_defaults_low\[8\] -rlabel metal3 820 4012 820 4012 0 gpio_defaults_low\[9\] -rlabel metal1 1844 1938 1844 1938 0 gpio_defaults_low\[5\] -rlabel metal1 1472 3502 1472 3502 0 gpio_defaults_low\[0\] -rlabel metal1 1932 3638 1932 3638 0 gpio_defaults_high\[1\] -rlabel metal1 1104 2414 1104 2414 0 gpio_defaults_low\[6\] << properties >> string FIXED_BBOX 0 0 3400 5600 << end >> diff --git a/scripts/gen_gpio_defaults.py b/scripts/gen_gpio_defaults.py index dc19ce45..9fa2ffb2 100755 --- a/scripts/gen_gpio_defaults.py +++ b/scripts/gen_gpio_defaults.py @@ -59,13 +59,14 @@ # gpio_defaults[8] 7.965 20.485 # gpio_defaults[9] 4.745 20.485 # gpio_defaults[10] 5.205 15.045 -# gpio_defaults[11] 12.015 9.605 +# gpio_defaults[11] 12.105 9.605 # gpio_defaults[12] 8.885 9.605 #------------------------------------------------------------------- import os import sys import re +import subprocess def usage(): print('Usage:') @@ -84,7 +85,7 @@ if __name__ == '__main__': # Coordinate pairs in microns for the zero position on each bit via_pos = [[7.505, 17.425], [11.645, 17.425], [4.745, 6.545], [7.965, 6.545], [11.645, 6.545], [5.205, 9.605], [5.205, 11.985], [8.425, 15.045], - [7.965, 20.485], [4.745, 20.485], [5.205, 15.045], [12.015, 9.605], + [7.965, 20.485], [4.745, 20.485], [5.205, 15.045], [12.105, 9.605], [8.885, 9.605]] optionlist = [] @@ -329,6 +330,15 @@ if __name__ == '__main__': if testmode: print('Test only: Caravel core layout:') + + # Check for compressed layout + is_compressed = False + if not os.path.isfile(caravel_path + '/mag/caravel_core.mag'): + if os.path.isfile(caravel_path + '/mag/caravel_core.mag.gz'): + is_compressed = True + print('Uncompressing caravel_core.mag') + subprocess.run(['gunzip', caravel_path + '/mag/caravel_core.mag.gz']) + with open(caravel_path + '/mag/caravel_core.mag', 'r') as ifile: maglines = ifile.read().splitlines() outlines = [] @@ -363,6 +373,11 @@ if __name__ == '__main__': for outline in outlines: print(outline, file=ofile) + if is_compressed: + print('Compressing caravel_core.mag') + subprocess.run(['gzip', '-n', '--best', caravel_path + + '/mag/caravel_core.mag']) + # Do the same to the core gate-level verilog inst1rex = re.compile('[ \t]*(gpio_defaults_block_?[0-1]?[0-9A-Fa-f]*)[ \t]+.?gpio_defaults_block_([0-9]+).([0-9]+)') diff --git a/scripts/verify_defaults_blocks.py b/scripts/verify_defaults_blocks.py new file mode 100755 index 00000000..03313007 --- /dev/null +++ b/scripts/verify_defaults_blocks.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# +# run_lvs_defaults_blocks.py +# +# Check operation of gen_gpio_defaults.py by running simulation on all +# gpio_defaults_block_XXXX layouts. +# +# 1) create special user_defaults.v file +# 2) run gen_gpio_defaults.py script +# 3) for each gpio_default_block_XXXX layout in mag/: +# 1) extract the layout and generate a SPICE netlist +# 2) parse the netlist for the names of pins connected to conb cells +# 3) determine the connectivity according to the value of pins HI and LO +# 4) print out the binary value of the layout cell's output. +# + +import os +import re +import sys +import subprocess + +bits_list = ["0000", "0001", "0002", "0004", "0008", "0010", "0020", "0040", + "0080", "0100", "0200", "0400", "0800", "1000", "1fff", "2000", + "1ffe", "1ffd", "1ffb", "1ff7", "1fef", "1fdf", "1fbf", "1f7f", + "1eff", "1dff", "1bff", "17ff", "0fff", "1555", "0aaa", "0f0f", + "10f0"] + +expected_results = [ + "0000000000000", "0000000000001", "0000000000010", "0000000000100", + "0000000001000", "0000000010000", "0000000100000", "0000001000000", + "0000010000000", "0000100000000", "0001000000000", "0010000000000", + "0100000000000", "1000000000000", "1111111111111", "1000000000000", + "1111111111110", "1111111111101", "1111111111011", "1111111110111", + "1111111101111", "1111111011111", "1111110111111", "1111101111111", + "1111011111111", "1110111111111", "1101111111111", "1011111111111", + "0111111111111", "1010101010101", "0101010101010", "0111100001111", + "1000011110000", "0010000000011", "0100000000001", "1100000000011"] + +# IMPORTANT NOTE: This script is invasive and changes files and does not change +# them back. Run this only in a git branch which can be removed afterward. + +with open('verilog/rtl/user_defines.v', 'w') as ofile: + print('`default_nettype none', file=ofile) + print('`ifndef __USER_DEFINES_H', file=ofile) + print('`define __USER_DEFINES_H', file=ofile) + i = 5 + for bits in bits_list: + print("`define USER_CONFIG_GPIO_" + str(i) + "_INIT 13'h" + bits, file=ofile) + i = i + 1 + print('`endif // __USER_DEFINES_H', file=ofile) + +subprocess.run('scripts/gen_gpio_defaults.py') + +# Add the defaults for channels 0 to 5 to the list. +bits_list.extend(["0403", "0801", "1803"]) + +os.chdir('mag') +for bits in bits_list: + if not os.path.isfile('gpio_defaults_block_' + bits + '.spice'): + with open('gpio_verify.tcl', 'w') as ofile: + print('load gpio_defaults_block_' + bits, file=ofile) + print('extract do local', file=ofile) + print('extract do local', file=ofile) + print('extract no all', file=ofile) + print('extract all', file=ofile) + print('ext2spice lvs', file=ofile) + print('ext2spice', file=ofile) + print('quit', file=ofile) + + # Depend on the .magicrc file in the mag/ directory? + subprocess.run(['magic', '-dnull', '-noconsole', 'gpio_verify.tcl']) + +conbrex = re.compile('^Xgpio_default_value.*\[([0-9]+).*\]') + +i = 0 +for bits in bits_list: + # Read SPICE file and verify + bits_verify = ['X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'] + with open('gpio_defaults_block_' + bits + '.spice', 'r') as ifile: + spicelines = ifile.read().splitlines() + for line in spicelines: + cmatch = conbrex.match(line) + if cmatch: + bitnum = int(cmatch.group(1)) + tokens = line.split() + if 'gpio_defaults' in tokens[5] and 'gpio_default_value' in tokens[6]: + bits_verify[bitnum] = '1' + elif 'gpio_defaults' in tokens[6] and 'gpio_default_value' in tokens[5]: + bits_verify[bitnum] = '0' + else: + print('Bad line in netlist: ' + line) + # Put zero bit at end + bits_verify.reverse() + verify_string = ''.join(bits_verify) + print('Layout for default ' + bits + ' has configuration ' + verify_string) + if verify_string != expected_results[i]: + print('***ERROR: Expected bit string ' + expected_results[i] + ' but got ' + verify_string + '!') + i = i + 1 + + +# Remove all .ext and .spice files +for bits in bits_list: + if os.path.isfile('gpio_defaults_block_' + bits + '.ext'): + os.remove('gpio_defaults_block_' + bits + '.ext') + if os.path.isfile('gpio_defaults_block_' + bits + '.spice'): + os.remove('gpio_defaults_block_' + bits + '.spice') + +# Remove the input file for magic +os.remove('gpio_verify.tcl')