mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-06-28 09:16:22 -04:00
A couple simple changes which adds a caveat to the README about #2535 and removes some unnecessary hard coded paths which makes development easier on platforms such as Nix
307 lines
11 KiB
Python
Executable file
307 lines
11 KiB
Python
Executable file
# Copyright 2024 Thales DIS France SAS
|
|
#
|
|
# Licensed under the Solderpad Hardware License, Version 2.1 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
|
# You may obtain a copy of the License at https://solderpad.org/licenses/
|
|
#
|
|
# Original Author: Jean-Roch COULON - Thales
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
import re
|
|
import sys
|
|
import os
|
|
|
|
from classes import Parameter
|
|
from classes import PortIO
|
|
from define_blacklist import define_blacklist
|
|
from parameters_extractor import parameters_extractor
|
|
from parameters_extractor import writeout_parameter_table
|
|
from parameters_extractor import writeout_parameter_table_adoc
|
|
|
|
HEADER_RST = """\
|
|
..
|
|
Copyright 2024 Thales DIS France SAS
|
|
Licensed under the Solderpad Hardware License, Version 2.1 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
|
You may obtain a copy of the License at https://solderpad.org/licenses/
|
|
|
|
Original Author: Jean-Roch COULON - Thales
|
|
|
|
"""
|
|
|
|
HEADER_ADOC = """\
|
|
////
|
|
Copyright 2024 Thales DIS France SAS
|
|
Licensed under the Solderpad Hardware License, Version 2.1 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
|
You may obtain a copy of the License at https://solderpad.org/licenses/
|
|
|
|
Original Author: Jean-Roch COULON - Thales
|
|
////
|
|
|
|
"""
|
|
|
|
DEFAULT_PARAMS = {
|
|
'RVE': False,
|
|
'RVQ': False,
|
|
'RVZabha': False,
|
|
'RVZacas': False,
|
|
'RVZawrs': False,
|
|
'RVZcmop': False,
|
|
'RVZfa': False,
|
|
'RVZfbf-RZvfbf': False,
|
|
'RVZfh': False,
|
|
'RVZfinx': False,
|
|
'RVZicbo': False,
|
|
'RVZicfilp': False,
|
|
'RVZifencei': False,
|
|
'RVZihintntl': False,
|
|
'RVZihintpause': False,
|
|
'RVZimop': False,
|
|
'RVZk': False,
|
|
'RVZpm': False,
|
|
'RVZsmcdeleg': False,
|
|
'RVZsmcntrpmf': False,
|
|
'RVZsmcsrind-RVZsscsrind': False,
|
|
'RVZsmctr': False,
|
|
'RVZsmdbltrp': False,
|
|
'RVZsmepmp': False,
|
|
'RVZsmmpm': False,
|
|
'RVZsmrnmi': False,
|
|
'RVZsmstateen': False,
|
|
'RVZsscofpmf': False,
|
|
'RVZssdbltrp': False,
|
|
'RVZsstc': False,
|
|
'RVZtso': False,
|
|
'RVZvk': False,
|
|
'SV': 'SV0'
|
|
}
|
|
|
|
def print_to_rst(pathout, target, module, ports, comments):
|
|
fileout = f"{pathout}/port_{module}.rst"
|
|
print("Output file " + fileout)
|
|
|
|
with open(fileout, "w", encoding="utf-8") as fout:
|
|
fout.write(HEADER_RST)
|
|
fout.write(f".. _CVA6_{module}_ports:\n\n")
|
|
fout.write(f".. list-table:: **{module} module** IO ports\n")
|
|
fout.write(" :header-rows: 1\n")
|
|
fout.write("\n")
|
|
fout.write(" * - Signal\n")
|
|
fout.write(" - IO\n")
|
|
fout.write(" - Description\n")
|
|
fout.write(" - connexion\n")
|
|
fout.write(" - Type\n")
|
|
for i, port in enumerate(ports):
|
|
fout.write("\n")
|
|
fout.write(f" * - ``{port.name}``\n")
|
|
fout.write(f" - {port.direction}\n")
|
|
fout.write(f" - {port.description}\n")
|
|
fout.write(f" - {port.connexion}\n")
|
|
fout.write(f" - {port.data_type}\n")
|
|
fout.write("\n")
|
|
if len(comments) != 0:
|
|
fout.write(
|
|
f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n"
|
|
)
|
|
fout.write("\n")
|
|
for comment in comments:
|
|
fout.write(f"| {comment[0]},\n| {comment[1]}\n")
|
|
fout.write("\n")
|
|
|
|
def print_to_adoc(pathout, target, module, ports, comments):
|
|
fileout = f"{pathout}/port_{module}.adoc"
|
|
print("Output file " + fileout)
|
|
|
|
# format comments
|
|
for comment in comments:
|
|
for i in range(len(comment)):
|
|
comment[i] = comment[i].replace('``', '`')
|
|
comment[i] = comment[i].replace('|', '*')
|
|
|
|
with open(fileout, "w", encoding="utf-8") as fout:
|
|
fout.write(HEADER_ADOC)
|
|
|
|
fout.write(f"[[_CVA6_{module}_ports]]\n\n")
|
|
|
|
fout.write(f".*{module} module* IO ports\n")
|
|
fout.write("|===\n")
|
|
fout.write("|Signal | IO | Description | connexion | Type\n\n")
|
|
|
|
for port in ports:
|
|
fout.write(f"|`{port.name}` | {port.direction} | {port.description} | {port.connexion} | {port.data_type}\n\n")
|
|
fout.write("|===\n")
|
|
|
|
if len(comments) != 0:
|
|
fout.write(
|
|
f"Due to {target} configuration, some ports are tied to a static value. These ports do not appear in the above table, they are listed below\n\n"
|
|
)
|
|
for comment in comments:
|
|
fout.write(f"{comment[0]},::\n* {comment[1]}\n")
|
|
fout.write("\n")
|
|
|
|
def _format_parameter_adoc(name, value):
|
|
if type(value) is bool:
|
|
ret = str(value).lower()
|
|
else:
|
|
ret = str(value)
|
|
return f":{name}: {ret}\n"
|
|
|
|
def main():
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--target", required=True)
|
|
parser.add_argument("--gen-config", help="Generate target variables documentation file")
|
|
parser.add_argument("--gen-parameters", help="Generate target parameters files")
|
|
parser.add_argument("--gen-ports-folder", help="Generate target ports files")
|
|
args = parser.parse_args()
|
|
|
|
target = args.target
|
|
|
|
parameters = parameters_extractor(target)
|
|
|
|
# User_cfg
|
|
export_user_cfg_doc("01_cva6_user/user_cfg_doc.rst", parameters)
|
|
|
|
# Parameters
|
|
if args.gen_parameters is not None:
|
|
os.makedirs(os.path.dirname(args.gen_parameters), exist_ok=True)
|
|
writeout_parameter_table_adoc(args.gen_parameters, parameters, target)
|
|
print(f"File {args.gen_parameters} written")
|
|
|
|
# Config
|
|
if args.gen_config is not None:
|
|
os.makedirs(os.path.dirname(args.gen_config), exist_ok=True)
|
|
with open(args.gen_config, "w") as fout:
|
|
fout.write(f":ohg-config: {target.upper()}\n")
|
|
for name, value in DEFAULT_PARAMS.items():
|
|
fout.write(_format_parameter_adoc(name, value))
|
|
for name, parameter in parameters.items():
|
|
fout.write(_format_parameter_adoc(name, parameter.value))
|
|
print(f"File {args.gen_config} written")
|
|
|
|
# Ports
|
|
if args.gen_ports_folder is not None:
|
|
file = []
|
|
file.append("../core/cva6.sv")
|
|
file.append("../core/frontend/frontend.sv")
|
|
file.append("../core/frontend/bht.sv")
|
|
file.append("../core/frontend/bht2lvl.sv")
|
|
file.append("../core/frontend/btb.sv")
|
|
file.append("../core/frontend/ras.sv")
|
|
file.append("../core/frontend/instr_queue.sv")
|
|
file.append("../core/frontend/instr_scan.sv")
|
|
file.append("../core/instr_realign.sv")
|
|
file.append("../core/id_stage.sv")
|
|
file.append("../core/issue_stage.sv")
|
|
file.append("../core/ex_stage.sv")
|
|
file.append("../core/commit_stage.sv")
|
|
file.append("../core/controller.sv")
|
|
file.append("../core/csr_regfile.sv")
|
|
file.append("../core/decoder.sv")
|
|
file.append("../core/compressed_decoder.sv")
|
|
file.append("../core/scoreboard.sv")
|
|
file.append("../core/issue_read_operands.sv")
|
|
file.append("../core/alu.sv")
|
|
file.append("../core/branch_unit.sv")
|
|
file.append("../core/csr_buffer.sv")
|
|
file.append("../core/mult.sv")
|
|
file.append("../core/multiplier.sv")
|
|
file.append("../core/serdiv.sv")
|
|
file.append("../core/load_store_unit.sv")
|
|
file.append("../core/load_unit.sv")
|
|
file.append("../core/store_unit.sv")
|
|
file.append("../core/lsu_bypass.sv")
|
|
file.append("../core/cvxif_fu.sv")
|
|
file.append("../core/cache_subsystem/cva6_hpdcache_subsystem.sv")
|
|
|
|
black_list = define_blacklist(parameters)
|
|
|
|
for filein in file:
|
|
comments = []
|
|
a = re.match(r".*\/(.*).sv", filein)
|
|
module = a.group(1)
|
|
print("Input file " + filein)
|
|
ports = []
|
|
with open(filein, "r", encoding="utf-8") as fin:
|
|
description = "none"
|
|
connexion = "none"
|
|
for line in fin:
|
|
e = re.match(r"^ +(?:(in|out))put +([\S]*(?: +.* *|)) ([\S]*)\n", line)
|
|
d = re.match(r"^ +\/\/ (.*) - ([\S]*)\n", line)
|
|
if d:
|
|
description = d.group(1)
|
|
connexion = d.group(2)
|
|
if e:
|
|
name = e.group(3)
|
|
name = name.replace(",", "")
|
|
data_type = e.group(2)
|
|
data_type = data_type.replace(" ", "")
|
|
if connexion in black_list:
|
|
for i, comment in enumerate(comments):
|
|
if black_list[connexion][0] == comment[0]:
|
|
comment[1] = (
|
|
comment[1]
|
|
+ f"\n| ``{name}`` {e.group(1)}put is tied to {black_list[connexion][1]}"
|
|
)
|
|
break
|
|
else:
|
|
comments.append(
|
|
[
|
|
black_list[connexion][0],
|
|
f"``{name}`` {e.group(1)}put is tied to {black_list[connexion][1]}",
|
|
]
|
|
)
|
|
else:
|
|
if name in black_list:
|
|
for i, comment in enumerate(comments):
|
|
if black_list[name][0] == comment[0]:
|
|
comment[1] = (
|
|
comment[1]
|
|
+ f"\n| ``{name}`` {e.group(1)}put is tied to {black_list[name][1]}"
|
|
)
|
|
break
|
|
else:
|
|
comments.append(
|
|
[
|
|
black_list[name][0],
|
|
f"``{name}`` {e.group(1)}put is tied to {black_list[name][1]}",
|
|
]
|
|
)
|
|
else:
|
|
ports.append(
|
|
PortIO(
|
|
name, e.group(1), data_type, description, connexion
|
|
)
|
|
)
|
|
description = "none"
|
|
connexion = "none"
|
|
|
|
print_to_adoc(args.gen_ports_folder, target, module, ports, comments)
|
|
|
|
def export_user_cfg_doc(out_path, params):
|
|
with open(out_path, "w", encoding="utf-8") as f:
|
|
f.write(HEADER_RST)
|
|
f.write("""\
|
|
.. _cva6_user_cfg_doc:
|
|
|
|
.. list-table:: ``cva6_user_cfg_t`` parameters
|
|
:header-rows: 1
|
|
|
|
* - Name
|
|
- Type
|
|
- Description
|
|
""")
|
|
for name, param in params.items():
|
|
f.write("\n")
|
|
f.write(f" * - ``{name}``\n")
|
|
f.write(f" - ``{param.datatype.strip()}``\n")
|
|
f.write(f" - {param.description}\n")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|