mirror of https://github.com/efabless/caravel.git
This commit fixes the issue with the user ID programming block not
getting changed by "make ship" because the build is done in a place where the path pointer to the user_id_programming GDS still points back to the original caravel repository, not the user project repository. The user_id_programming GDS was removed (no longer used), the user_id_programming.mag file was modified to remove the path pointer to the GDS, and the set_user_id.py script was modified to make changes directly to the user_id_programming.mag file instead of the GDS. An additional method was added to the set_user_id.py script to modify the gate-level verilog/gl/user_id_programming.v to make the user ID correct for gate-level testbench simulations.
This commit is contained in:
parent
191139bf0e
commit
53abff5bbf
2
Makefile
2
Makefile
|
@ -1133,10 +1133,10 @@ __set_user_id:
|
||||||
mkdir -p ./signoff/build
|
mkdir -p ./signoff/build
|
||||||
# Update info.yaml
|
# Update info.yaml
|
||||||
# sed -r "s/^(\s*project_id\s*:\s*).*/\1${USER_ID}/" -i info.yaml
|
# sed -r "s/^(\s*project_id\s*:\s*).*/\1${USER_ID}/" -i info.yaml
|
||||||
cp $(CARAVEL_ROOT)/gds/user_id_programming.gds ./gds/user_id_programming.gds
|
|
||||||
cp $(CARAVEL_ROOT)/mag/user_id_programming.mag ./mag/user_id_programming.mag
|
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)/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.v ./verilog/rtl/caravel.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
|
python3 $(CARAVEL_ROOT)/scripts/set_user_id.py $(USER_ID) $(shell pwd) 2>&1 | tee ./signoff/build/set_user_id.out
|
||||||
|
|
||||||
.PHONY: gpio_defaults
|
.PHONY: gpio_defaults
|
||||||
|
|
Binary file not shown.
|
@ -3154,6 +3154,4 @@ rlabel metal5 s 1104 2512 5980 2832 4 VGND
|
||||||
port 34 nsew
|
port 34 nsew
|
||||||
<< properties >>
|
<< properties >>
|
||||||
string FIXED_BBOX 0 0 7109 7077
|
string FIXED_BBOX 0 0 7109 7077
|
||||||
string GDS_FILE ../gds/user_id_programming.gds
|
|
||||||
string GDS_START 0
|
|
||||||
<< end >>
|
<< end >>
|
||||||
|
|
|
@ -184,14 +184,9 @@ if __name__ == '__main__':
|
||||||
print('Setting project user ID to: ' + user_id_value)
|
print('Setting project user ID to: ' + user_id_value)
|
||||||
|
|
||||||
magpath = user_project_path + '/mag'
|
magpath = user_project_path + '/mag'
|
||||||
gdspath = user_project_path + '/gds'
|
|
||||||
vpath = user_project_path + '/verilog'
|
vpath = user_project_path + '/verilog'
|
||||||
errors = 0
|
errors = 0
|
||||||
|
|
||||||
if not os.path.isdir(gdspath):
|
|
||||||
print('No directory ' + gdspath + ' found (path to GDS).')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not os.path.isdir(vpath):
|
if not os.path.isdir(vpath):
|
||||||
print('No directory ' + vpath + ' found (path to verilog).')
|
print('No directory ' + vpath + ' found (path to verilog).')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -200,44 +195,24 @@ if __name__ == '__main__':
|
||||||
print('No directory ' + magpath + ' found (path to magic databases).')
|
print('No directory ' + magpath + ' found (path to magic databases).')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print('Step 1: Modify GDS of the user_id_programming subcell')
|
print('Step 1: Modify layout of the user_id_programming subcell')
|
||||||
|
|
||||||
# Bytes leading up to via position are:
|
# Bytes leading up to via position are:
|
||||||
viarec = "00 06 0d 02 00 43 00 06 0e 02 00 2c 00 2c 10 03 "
|
viarec = "00 06 0d 02 00 43 00 06 0e 02 00 2c 00 2c 10 03 "
|
||||||
viabytes = bytes.fromhex(viarec)
|
viabytes = bytes.fromhex(viarec)
|
||||||
|
|
||||||
# Check for either GDS file being gzipped
|
# Read the ID programming layout. If a backup was made of the
|
||||||
gdsbakgz = gdspath + '/user_id_prog_zero.gds.gz'
|
# zero-value program, then use it.
|
||||||
gdsfilegz = gdspath + '/user_id_programming.gds.gz'
|
|
||||||
|
|
||||||
if os.path.isfile(gdsbakgz):
|
magbak = magpath + '/user_id_prog_zero.mag'
|
||||||
subprocess.run(['gunzip', gdsbakgz],
|
magfile = magpath + '/user_id_programming.mag'
|
||||||
stdout = subprocess.DEVNULL,
|
|
||||||
stderr = subprocess.DEVNULL)
|
if os.path.isfile(magbak):
|
||||||
zero_zipped = True
|
with open(magbak, 'r') as ifile:
|
||||||
|
magdata = ifile.read()
|
||||||
else:
|
else:
|
||||||
zero_zipped = False
|
with open(magfile, 'r') as ifile:
|
||||||
|
magdata = ifile.read()
|
||||||
if os.path.isfile(gdsfilegz):
|
|
||||||
subprocess.run(['gunzip', gdsfilegz],
|
|
||||||
stdout = subprocess.DEVNULL,
|
|
||||||
stderr = subprocess.DEVNULL)
|
|
||||||
file_zipped = True
|
|
||||||
else:
|
|
||||||
file_zipped = False
|
|
||||||
|
|
||||||
# Read the GDS file. If a backup was made of the zero-value
|
|
||||||
# program, then use it.
|
|
||||||
|
|
||||||
gdsbak = gdspath + '/user_id_prog_zero.gds'
|
|
||||||
gdsfile = gdspath + '/user_id_programming.gds'
|
|
||||||
|
|
||||||
if os.path.isfile(gdsbak):
|
|
||||||
with open(gdsbak, 'rb') as ifile:
|
|
||||||
gdsdata = ifile.read()
|
|
||||||
else:
|
|
||||||
with open(gdsfile, 'rb') as ifile:
|
|
||||||
gdsdata = ifile.read()
|
|
||||||
|
|
||||||
for i in range(0,32):
|
for i in range(0,32):
|
||||||
# Ignore any zero bits.
|
# Ignore any zero bits.
|
||||||
|
@ -256,72 +231,45 @@ if __name__ == '__main__':
|
||||||
xurum = xum + 0.085
|
xurum = xum + 0.085
|
||||||
yurum = yum + 0.085
|
yurum = yum + 0.085
|
||||||
|
|
||||||
# Get the 4-byte hex values for the corner coordinates
|
# Get the values for the corner coordinates in magic internal units
|
||||||
xllnm = round(xllum * 1000)
|
xlli = int(round(xllum * 200))
|
||||||
yllnm = round(yllum * 1000)
|
ylli = int(round(yllum * 200))
|
||||||
xllhex = '{0:08x}'.format(xllnm)
|
xuri = int(round(xurum * 200))
|
||||||
yllhex = '{0:08x}'.format(yllnm)
|
yuri = int(round(yurum * 200))
|
||||||
xurnm = round(xurum * 1000)
|
|
||||||
yurnm = round(yurum * 1000)
|
viaoldposdata = 'rect ' + xlli + ' ' + ylli + ' ' + xuri + ' ' + yuri
|
||||||
xurhex = '{0:08x}'.format(xurnm)
|
|
||||||
yurhex = '{0:08x}'.format(yurnm)
|
|
||||||
|
|
||||||
# Magic's GDS output for vias always starts at the lower left
|
|
||||||
# corner and goes counterclockwise, repeating the first point.
|
|
||||||
viaoldposdata = viarec + xllhex + yllhex + xurhex + yllhex
|
|
||||||
viaoldposdata += xurhex + yurhex + xllhex + yurhex + xllhex + yllhex
|
|
||||||
|
|
||||||
# For "one" bits, the X position is moved 0.92 microns to the left
|
# For "one" bits, the X position is moved 0.92 microns to the left
|
||||||
newxllum = xllum - 0.92
|
newxllum = xllum - 0.92
|
||||||
newxurum = xurum - 0.92
|
newxurum = xurum - 0.92
|
||||||
|
|
||||||
# Get the 4-byte hex values for the new corner coordinates
|
# Get the values for the new corner coordinates in magic internal units
|
||||||
newxllnm = round(newxllum * 1000)
|
newxlli = int(round(newxllum * 200))
|
||||||
newxllhex = '{0:08x}'.format(newxllnm)
|
newxuri = int(round(newxurum * 200))
|
||||||
newxurnm = round(newxurum * 1000)
|
|
||||||
newxurhex = '{0:08x}'.format(newxurnm)
|
|
||||||
|
|
||||||
vianewposdata = viarec + newxllhex + yllhex + newxurhex + yllhex
|
vianewposdata = 'rect ' + newxlli + ' ' + ylli + ' ' + newxuri + ' ' + yuri
|
||||||
vianewposdata += newxurhex + yurhex + newxllhex + yurhex + newxllhex + yllhex
|
|
||||||
|
|
||||||
# Diagnostic
|
# Diagnostic
|
||||||
if debugmode:
|
if debugmode:
|
||||||
print('Bit ' + str(i) + ':')
|
print('Bit ' + str(i) + ':')
|
||||||
print('Via position ({0:3.2f}, {1:3.2f}) to ({2:3.2f}, {3:3.2f})'.format(xllum, yllum, xurum, yurum))
|
print('Via position ({0:3.2f}, {1:3.2f}) to ({2:3.2f}, {3:3.2f})'.format(xllum, yllum, xurum, yurum))
|
||||||
print('Old hex string = ' + viaoldposdata)
|
print('Old string = "' + viaoldposdata + '"')
|
||||||
print('New hex string = ' + vianewposdata)
|
print('New string = "' + vianewposdata + '"')
|
||||||
|
|
||||||
# Convert hex strings to byte arrays
|
|
||||||
viaoldbytedata = bytearray.fromhex(viaoldposdata)
|
|
||||||
vianewbytedata = bytearray.fromhex(vianewposdata)
|
|
||||||
|
|
||||||
# Replace the old data with the new
|
# Replace the old data with the new
|
||||||
if viaoldbytedata not in gdsdata:
|
if viaoldposdata not in gdsdata:
|
||||||
print('Error: via not found for bit position ' + str(i))
|
print('Error: via not found for bit position ' + str(i))
|
||||||
errors += 1
|
errors += 1
|
||||||
else:
|
else:
|
||||||
gdsdata = gdsdata.replace(viaoldbytedata, vianewbytedata)
|
magdata == magdata.replace(viaoldposdata, vianewposdata)
|
||||||
|
|
||||||
if errors == 0:
|
if errors == 0:
|
||||||
# Keep a copy of the original
|
# Keep a copy of the original
|
||||||
if not os.path.isfile(gdsbak):
|
if not os.path.isfile(magbak):
|
||||||
if file_zipped:
|
os.rename(magfile, magbak)
|
||||||
if os.path.isfile(gdsfilegz):
|
|
||||||
os.rename(gdsfilegz, gdsbakgz)
|
|
||||||
else:
|
|
||||||
os.rename(gdsfile, gdsbak)
|
|
||||||
subprocess.run(['gzip', gdsbak, '-n', '--best'],
|
|
||||||
stdout = subprocess.DEVNULL,
|
|
||||||
stderr = subprocess.DEVNULL)
|
|
||||||
else:
|
|
||||||
os.rename(gdsfile, gdsbak)
|
|
||||||
|
|
||||||
with open(gdsfile, 'wb') as ofile:
|
with open(magfile, 'w') as ofile:
|
||||||
ofile.write(gdsdata)
|
ofile.write(magdata)
|
||||||
if file_zipped:
|
|
||||||
subprocess.run(['gzip', gdsfile, '-n', '--best'],
|
|
||||||
stdout = subprocess.DEVNULL,
|
|
||||||
stderr = subprocess.DEVNULL)
|
|
||||||
|
|
||||||
print('Done!')
|
print('Done!')
|
||||||
|
|
||||||
|
@ -330,7 +278,7 @@ if __name__ == '__main__':
|
||||||
print('Ending process.')
|
print('Ending process.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print('Step 2: Add user project ID parameter to verilog.')
|
print('Step 2: Add user project ID parameter to source verilog.')
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
with open(vpath + '/rtl/caravel.v', 'r') as ifile:
|
with open(vpath + '/rtl/caravel.v', 'r') as ifile:
|
||||||
|
@ -354,7 +302,34 @@ if __name__ == '__main__':
|
||||||
print('Ending process.')
|
print('Ending process.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print('Step 3: Add user project ID text to top level layout.')
|
print('Step 3: Add user project ID parameter to gate-level verilog.')
|
||||||
|
|
||||||
|
changed = False
|
||||||
|
with open(vpath + '/gl/user_id_programming.v', 'r') as ifile:
|
||||||
|
vdata = ifile.read()
|
||||||
|
|
||||||
|
for i in range(0,32):
|
||||||
|
# Ignore any zero bits.
|
||||||
|
if user_id_bits[i] == '0':
|
||||||
|
continue
|
||||||
|
|
||||||
|
outdata = vdata.replace('high[' + str(i) + ']', 'XXXX')
|
||||||
|
outdata = outdata.replace('low[' + str(i) + ']', 'high[' + str(i) + ']')
|
||||||
|
outdata = outdata.replace('XXXX', 'low[' + str(i) + ']')
|
||||||
|
outdata = outdata.replace('LO(mask_rev[' + str(i) + ']',
|
||||||
|
'HI(mask_rev[' + str(i) + ']')
|
||||||
|
outdata = outdata.replace('HI(\\user_proj_id_low', 'LO(\\user_proj_id_low')
|
||||||
|
|
||||||
|
if changed:
|
||||||
|
with open(vpath + '/gl/user_id_programming.v', 'w') as ofile:
|
||||||
|
ofile.write(outdata)
|
||||||
|
print('Done!')
|
||||||
|
else:
|
||||||
|
print('Error: No substitutions done on verilog/gl/user_id_programming.v.')
|
||||||
|
print('Ending process.')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print('Step 4: Add user project ID text to top level layout.')
|
||||||
|
|
||||||
with open(magpath + '/user_id_textblock.mag', 'r') as ifile:
|
with open(magpath + '/user_id_textblock.mag', 'r') as ifile:
|
||||||
maglines = ifile.read().splitlines()
|
maglines = ifile.read().splitlines()
|
||||||
|
|
Loading…
Reference in New Issue