blob: a3f8976ec8f5efe07acfae69e911624f8a7b0af1 [file] [log] [blame] [edit]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 The SkyWater PDK Authors.
#
# Use of this source code is governed by the Apache 2.0
# license that can be found in the LICENSE file or at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
import os
import sys
import json
copyright_header = """\
// Copyright 2020 The Skywater PDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
"""
include_header = """\
`ifndef VERILOG_MODE_SIMPLE
`ifndef VERILOG_MODE_BLACKBOX
`ifndef VERILOG_MODE_FULL
// No VERILOG_MODE_XXX defined, fallback to VERILOG_MODE_SIMPLE
`define VERILOG_MODE_SIMPLE 1
`endif
`endif
`endif
`ifdef VERILOG_MODE_SIMPLE
`include "{0}.simple.v"
`endif
`ifdef VERILOG_MODE_BLACKBOX
`include "{0}.blackbox.v"
`endif
`ifdef VERILOG_MODE_FULL
`include "{0}.full.v"
`endif
"""
module_header = """\
//# {library_name}: {cell_name} ({drive_value} {drive_name})
//# {description}
module {module_base_name}_{drive_value} (
{module_signal_defports}
`ifdef SC_USE_PG_PIN
{module_power_defports}
`endif
);
{module_base_name} (
{module_signal_ports}
`ifdef SC_USE_PG_PIN
{module_power_ports}
`endif
);
endmodule
"""
def write_verilog(mdata, outfile, drive=None):
with open(outfile, 'w') as f:
f.write(copyright_header)
f.write('\n')
f.write(include_header.format(mdata['fullname']))
f.write('\n')
if not drive:
return
drive_name, drive_value = drive
if not 'ports' in mdata:
return
module_signal_defports = []
module_signal_ports = []
for pname, ptype in mdata['ports']['signal']:
module_signal_defports.append("{} {}, ".format(ptype, pname))
module_signal_ports.append(pname)
module_signal_defports = "".join(module_signal_defports)
assert module_signal_defports.endswith(", "), module_signal_defports
module_signal_defports = module_signal_defports[:-2]
module_signal_ports = ", ".join(module_signal_ports)
module_power_defports = []
module_power_ports = []
for pname, ptype in mdata['ports']['power']:
module_power_defports.append(", {} {}".format('input', pname))
module_power_ports.append(", {}".format(pname))
module_power_defports = "".join(module_power_defports)
module_power_ports = "".join(module_power_ports)
library_name = "{} {}".format(
mdata['library']['name'].upper(), mdata['library']['type'])
f.write(module_header.format(
module_base_name = mdata['fullname'],
cell_name = mdata['name'],
library_name = library_name,
drive_name = drive_name,
drive_value = drive_value,
description = mdata.get('description', ''),
module_signal_defports = module_signal_defports,
module_signal_ports = module_signal_ports,
module_power_defports = module_power_defports,
module_power_ports = module_power_ports,
))
def echo_file(fname):
with open(fname) as f:
sys.stdout.write('\n')
sys.stdout.write('File: ')
sys.stdout.write(fname)
sys.stdout.write('\n')
sys.stdout.write('------\n')
sys.stdout.write(f.read())
sys.stdout.write('------\n')
sys.stdout.flush()
def process(cellpath):
md_json = os.path.join(cellpath, 'metadata.json')
if not os.path.exists(md_json):
return
assert os.path.exists(md_json), md_json
mdata = json.load(open(md_json))
drives = mdata.get('drives', [])
for d in drives:
assert len(d) == 1, d
drive_name = list(d.keys())[0]
drive_value = list(d.values())[0]
if drive_name == 'units':
pass
elif drive_name == 'lp_variant':
if drive_value == 0:
drive_value = 'lp'
else:
drive_value = 'lp'+str(drive_value+1)
elif drive_name == "minimum":
assert drive_value is None
drive_value = "m"
else:
raise TypeError("Unknown drive:"+repr(d))
dvfile = os.path.join(cellpath, "{}_{}.v".format(mdata['fullname'], drive_value))
write_verilog(mdata, dvfile, list(d.items())[0])
echo_file(dvfile)
if not drives:
outfile = os.path.join(cellpath, "{}.v".format(mdata['fullname']))
write_verilog(mdata, outfile)
echo_file(outfile)
def main(args):
for a in args:
process(a)
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))