| #!/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_PNG |
| {module_power_defports} |
| `endif |
| ); |
| |
| {module_base_name} ( |
| {module_signal_ports} |
| `ifdef SC_USE_PG_PNG |
| {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 |
| |
| 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] |
| 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:])) |