mirror of https://github.com/efabless/caravel.git
Merge branch 'main' into caravel-redesign-2-update-gpio_defaults_block
This commit is contained in:
commit
a2d661c085
10
Makefile
10
Makefile
|
@ -44,7 +44,7 @@ LARGE_FILES_GZ_SPLIT += $(addsuffix .00.split, $(ARCHIVES))
|
|||
|
||||
MCW_ROOT?=$(PWD)/mgmt_core_wrapper
|
||||
MCW ?=LITEX_VEXRISCV
|
||||
MPW_TAG ?= mpw-9a
|
||||
MPW_TAG ?= mpw-9b
|
||||
|
||||
PYTHON_BIN ?= python3
|
||||
|
||||
|
@ -122,9 +122,8 @@ __ship:
|
|||
drc off; \
|
||||
crashbackups stop; \
|
||||
addpath hexdigits; \
|
||||
addpath $(CARAVEL_ROOT)/mag; \
|
||||
addpath $(UPRJ_ROOT)/mag; \
|
||||
addpath $(MCW_ROOT)/mag; \
|
||||
addpath $(UPRJ_ROOT)/mag; \
|
||||
load user_project_wrapper; \
|
||||
property LEFview true; \
|
||||
property GDS_FILE $(UPRJ_ROOT)/gds/user_project_wrapper.gds; \
|
||||
|
@ -132,7 +131,8 @@ __ship:
|
|||
load $(UPRJ_ROOT)/mag/user_id_programming; \
|
||||
load $(UPRJ_ROOT)/mag/user_id_textblock; \
|
||||
load $(CARAVEL_ROOT)/maglef/simple_por; \
|
||||
load $(UPRJ_ROOT)/mag/caravel -dereference; \
|
||||
load $(UPRJ_ROOT)/mag/caravel_core -dereference; \
|
||||
load caravel -dereference; \
|
||||
select top cell; \
|
||||
expand; \
|
||||
cif *hier write disable; \
|
||||
|
@ -1144,7 +1144,7 @@ __set_user_id:
|
|||
# sed -r "s/^(\s*project_id\s*:\s*).*/\1${USER_ID}/" -i info.yaml
|
||||
cp $(CARAVEL_ROOT)/mag/user_id_programming.mag ./mag/user_id_programming.mag
|
||||
cp $(CARAVEL_ROOT)/mag/user_id_textblock.mag ./mag/user_id_textblock.mag
|
||||
cp $(CARAVEL_ROOT)/verilog/rtl/caravel.v ./verilog/rtl/caravel.v
|
||||
cp $(CARAVEL_ROOT)/verilog/rtl/caravel_core.v ./verilog/rtl/caravel_core.v
|
||||
cp $(CARAVEL_ROOT)/verilog/gl/user_id_programming.v ./verilog/gl/user_id_programming.v
|
||||
python3 $(CARAVEL_ROOT)/scripts/set_user_id.py $(USER_ID) $(shell pwd) 2>&1 | tee ./signoff/build/set_user_id.out
|
||||
|
||||
|
|
|
@ -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 >>
|
||||
|
|
4
manifest
4
manifest
|
@ -45,6 +45,6 @@ e0c6ead5e35c1ba01d923c482e953c2af9691524 verilog/rtl/mprj_io_buffer.v
|
|||
6f802b6ab7e6502160adfe41e313958b86d2c277 verilog/rtl/simple_por.v
|
||||
b9d6114a5067a04dd59cdd46fb988591c16743ce verilog/rtl/spare_logic_block.v
|
||||
8f0bec01c914efe790a09ffe62bbfe0781069e35 verilog/rtl/xres_buf.v
|
||||
c94f7ed5aa311f005513ace344991c8e6d3d19f5 scripts/set_user_id.py
|
||||
256190717faa72005cf7656d8443c4c0693b3f78 scripts/set_user_id.py
|
||||
98168b1fb6f80b196f9a05e725ec6ad99bc57ac6 scripts/generate_fill.py
|
||||
3210e724c6dc99563af780ff1778fada5b432604 scripts/compositor.py
|
||||
9e31b1bbbb03024d02d54f9da8d42b3837abc5e5 scripts/compositor.py
|
||||
|
|
|
@ -179,7 +179,7 @@ if __name__ == '__main__':
|
|||
# it's gigabytes anyway, so we don't want to deal with any
|
||||
# actual data. So it's just a placeholder.
|
||||
|
||||
print('load ' + project_with_id + '_fill_pattern -quiet', file=ofile)
|
||||
print('load ' + project_with_id + '_fill_pattern -silent', file=ofile)
|
||||
print('snap internal', file=ofile)
|
||||
print('box values {*}$bbox', file=ofile)
|
||||
print('paint comment', file=ofile)
|
||||
|
@ -188,7 +188,7 @@ if __name__ == '__main__':
|
|||
print('property FIXED_BBOX "$bbox"', file=ofile)
|
||||
|
||||
# Create a new project top level and place the fill cell.
|
||||
print('load ' + project_with_id + ' -quiet', file=ofile)
|
||||
print('load ' + project_with_id + ' -silent', file=ofile)
|
||||
print('box values 0 0 0 0', file=ofile)
|
||||
print('box position 6um 6um', file=ofile)
|
||||
print('getcell ' + project + ' child 0 0', file=ofile)
|
||||
|
@ -230,7 +230,7 @@ if __name__ == '__main__':
|
|||
for line in mproc.stdout.splitlines():
|
||||
print(line)
|
||||
if mproc.stderr:
|
||||
# NOTE: Until there is a "load -quiet" option in magic, loading
|
||||
# NOTE: Until there is a "load -silent" option in magic, loading
|
||||
# a new cell generates an error. This code ignores the error.
|
||||
newlines = []
|
||||
for line in mproc.stderr.splitlines():
|
||||
|
|
|
@ -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]+)')
|
||||
|
|
|
@ -180,7 +180,7 @@ if __name__ == '__main__':
|
|||
idrex = re.compile("parameter USER_PROJECT_ID = 32'h([0-9A-F]+);")
|
||||
|
||||
# Check if USER_PROJECT_ID has a non-zero value in caravel.v
|
||||
rtl_top_path = user_project_path + '/verilog/rtl/caravel.v'
|
||||
rtl_top_path = user_project_path + '/verilog/rtl/caravel_core.v'
|
||||
if os.path.isfile(rtl_top_path):
|
||||
with open(rtl_top_path, 'r') as ifile:
|
||||
vlines = ifile.read().splitlines()
|
||||
|
@ -307,7 +307,7 @@ if __name__ == '__main__':
|
|||
print('Step 2: Add user project ID parameter to source verilog.')
|
||||
|
||||
changed = False
|
||||
with open(vpath + '/rtl/caravel.v', 'r') as ifile:
|
||||
with open(vpath + '/rtl/caravel_core.v', 'r') as ifile:
|
||||
vlines = ifile.read().splitlines()
|
||||
outlines = []
|
||||
for line in vlines:
|
||||
|
@ -319,12 +319,12 @@ if __name__ == '__main__':
|
|||
outlines.append(oline)
|
||||
|
||||
if changed:
|
||||
with open(vpath + '/rtl/caravel.v', 'w') as ofile:
|
||||
with open(vpath + '/rtl/caravel_core.v', 'w') as ofile:
|
||||
for line in outlines:
|
||||
print(line, file=ofile)
|
||||
print('Done!')
|
||||
else:
|
||||
print('Error: No substitutions done on verilog/rtl/caravel.v.')
|
||||
print('Error: No substitutions done on verilog/rtl/caravel_core.v.')
|
||||
print('Ending process.')
|
||||
sys.exit(1)
|
||||
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
#!/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 gzip
|
||||
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.
|
||||
|
||||
if not os.path.isdir('verilog/rtl'):
|
||||
print('***ERROR: This script must be run from the caravel top level directory.')
|
||||
sys.exit(1)
|
||||
|
||||
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')
|
||||
|
||||
# Create the list of bits in order with channel number.
|
||||
ordered_bits_list = ["1803", "1803", "0403", "0801", "0403"]
|
||||
ordered_bits_list.extend(bits_list)
|
||||
|
||||
# Add the defaults for channels 0 to 5 to the list.
|
||||
bits_list.extend(["0403", "0801", "1803"])
|
||||
|
||||
os.chdir('mag')
|
||||
print('Generating netlists from gpio_defaults layouts')
|
||||
for bits in bits_list:
|
||||
if not os.path.isfile('gpio_defaults_block_' + bits + '.mag'):
|
||||
print('***ERROR: There is no layout file for gpio_defaults_block_' + bits + '!')
|
||||
elif 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
|
||||
print('Checking each generated layout netlist:')
|
||||
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']
|
||||
if not os.path.isfile('gpio_defaults_block_' + bits + '.spice'):
|
||||
print('***ERROR: No netlist generated for gpio_defaults_block_' + bits + '!')
|
||||
else:
|
||||
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
|
||||
|
||||
blrex = re.compile('^use gpio_defaults_block_([0-9a-zA-Z]+).*gpio_defaults_block_([0-9]+)$')
|
||||
found = 0
|
||||
|
||||
print('Checking modified caravel_core layout:')
|
||||
if os.path.isfile('caravel_core.mag.gz'):
|
||||
with gzip.open('caravel_core.mag.gz', 'r') as ifile:
|
||||
for line in ifile.readlines():
|
||||
bmatch = blrex.match(line.decode('ascii'))
|
||||
if bmatch:
|
||||
found = found + 1
|
||||
index = int(bmatch.group(2))
|
||||
value = bmatch.group(1)
|
||||
if value != ordered_bits_list[index]:
|
||||
print('***ERROR: Expected bit string ' + ordered_bits_list[index] + ' but got ' + value + ' for defaults block index ' + str(index) + '!')
|
||||
|
||||
elif os.path.isfile('caravel_core.mag'):
|
||||
with open('caravel_core.mag', 'r') as ifile:
|
||||
for line in ifile.readlines():
|
||||
bmatch = blrex.match(line.decode('ascii'))
|
||||
if bmatch:
|
||||
found = found + 1
|
||||
index = int(bmatch.group(2))
|
||||
value = bmatch.group(1)
|
||||
if value != ordered_bits_list[index]:
|
||||
print('***ERROR: Expected bit string ' + ordered_bits_list[index] + ' but got ' + value + ' for defaults block index ' + str(index) + '!')
|
||||
else:
|
||||
print('***ERROR: There is no caravel_core.mag(.gz) file. Did you run the script from the project top level?')
|
||||
|
||||
if found != 38:
|
||||
print('***ERROR: Found ' + str(found) + ' defaults blocks in caravel_core, not the expected 38!')
|
||||
|
||||
# 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')
|
Loading…
Reference in New Issue