#!/usr/bin/env python3 # Copyright 2022 Thales DIS design services SAS # # Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0 # You may obtain a copy of the License at https://solderpad.org/licenses/ # # Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com) import sys import os import argparse import re def setup_parser_config_generator(): parser = argparse.ArgumentParser() parser.add_argument("--default_config", type=str, default="cv64a6_imafdc_sv39", required=True, choices=["cv32a6_imac_sv0","cv32a6_imac_sv32","cv32a6_imafc_sv32","cv64a6_imafdc_sv39","cv32a60x"], help="Default configuration is one of the 4 preexisting configuration: \ cv32a6_imac_sv0, cv32a6_imac_sv32, cv32a6_imafc_sv32, cv64a6_imafdc_sv39") parser.add_argument("--isa", type=str, default=None, required=True, help="RISC-V ISA subset") parser.add_argument("--fpu", type=int, default=None, choices=[0,1], help="FPU enable ? 1 : enable, 0 : disable") parser.add_argument("--F16En", type=int, default=None, choices=[0,1], help="F16En enable ? 1 : enable, 0 : disable") parser.add_argument("--F16AltEn", type=int, default=None, choices=[0,1], help="F16AltEn enable ? 1 : enable, 0 : disable") parser.add_argument("--F8En", type=int, default=None, choices=[0,1], help="F8En enable ? 1 : enable, 0 : disable") parser.add_argument("--FVecEn", type=int, default=None, choices=[0,1], help="FVecEn enable ? 1 : enable, 0 : disable") parser.add_argument("--cvxif", type=int, default=None, choices=[0,1], help="CoreV-X-Interface enable ? 1 : enable, 0 : disable") parser.add_argument("--c_ext", type=int, default=None, choices=[0,1], help="C extension enable ? 1 : enable, 0 : disable") parser.add_argument("--a_ext", type=int, default=None, choices=[0,1], help="A extension enable ? 1 : enable, 0 : disable") parser.add_argument("--b_ext", type=int, default=None, choices=[0,1], help="B extension enable ? 1 : enable, 0 : disable") parser.add_argument("--AxiIdWidth", type=int, default=None, help="AXI transaction ID width") parser.add_argument("--AxiAddrWidth", type=int, default=None, help="AXI address width") parser.add_argument("--AxiDataWidth", type=int, default=None, help="AXI data width") parser.add_argument("--iuser_en", type=int, default=None, choices=[0,1], help="Fetch User enable ? 1 : enable, 0 : disable") parser.add_argument("--iuser_w", type=int, default=None, choices=list(range(1,64)), help="Fetch User Width ? [1-64]") parser.add_argument("--duser_en", type=int, default=None, choices=[0,1], help="Data User enable ? 1 : enable, 0 : disable") parser.add_argument("--duser_w", type=int, default=None, choices=list(range(1,64)), help="Data User Width ? [1-64]") parser.add_argument("--RenameEn", type=int, default=None, choices=[0,1], help="RenameEn ? 1 : enable, 0 : disable") parser.add_argument("--IcacheByteSize", type=int, default=None, help="Instruction cache size in bytes") parser.add_argument("--IcacheSetAssoc", type=int, default=None, help="Instruction cache associativity") parser.add_argument("--IcacheLineWidth", type=int, default=None, help="Instruction cache line width") parser.add_argument("--DcacheByteSize", type=int, default=None, help="Data cache size in bytes") parser.add_argument("--DcacheSetAssoc", type=int, default=None, help="Data cache associativity") parser.add_argument("--DcacheLineWidth", type=int, default=None, help="Data cache line width") parser.add_argument("--DcacheIdWidth", type=int, default=None, help="Data cache TID width") parser.add_argument("--MemTidWidth", type=int, default=None, help="Memory TID width") parser.add_argument("--WtDcacheWbufDepth", type=int, default=None, help="WT data cache WBUF depth") parser.add_argument("--NrCommitPorts", type=int, default=None, choices=[1,2], help="Number of commit ports") parser.add_argument("--NrScoreboardEntries", type=int, default=None, help="Number of scoreboard entries") parser.add_argument("--FPGAEn", type=int, default=None, choices=[0,1], help="Use FPGA-specific hardware") parser.add_argument("--NrLoadPipeRegs", type=int, default=None, help="Load latency") parser.add_argument("--NrStorePipeRegs", type=int, default=None, help="Store latency") parser.add_argument("--InstrTlbEntries", type=int, default=None, help="Number of instruction TLB entries") parser.add_argument("--DataTlbEntries", type=int, default=None, help="Number of data TLB entries") parser.add_argument("--RASDepth", type=int, default=None, help="Depth of Return Address Stack") parser.add_argument("--BTBEntries", type=int, default=None, help="Number of Branch Target Buffer entries") parser.add_argument("--BHTEntries", type=int, default=None, help="Number of Branch History Table entries") parser.add_argument("--NrPMPEntries", type=int, default=None, help="Number of PMP entries") parser.add_argument("--PerfCounterEn", type=int, default=None, help="Enable performance counters") parser.add_argument("--DcacheType", type=str, default=None, choices=["WB", "WT"], help="Cache type (WB or WT)") parser.add_argument("--MmuPresent", type=int, default=None, choices=[0, 1], help="Use an MMU ? 1 : enable, 0 : disable") parser.add_argument("--RvfiTrace", type=int, default=None, choices=[0, 1], help="Output an RVFI trace ? 1 : enable, 0 : disable") return parser ISA = "" MABI = "" Config = dict() MapArgsToParameter={ "xlen" : "CVA6ConfigXlen", "fpu" : "CVA6ConfigFpuEn", "F16En" : "CVA6ConfigF16En", "F16AltEn" : "CVA6ConfigF16AltEn", "F8En" : "CVA6ConfigF8En", "FVecEn" : "CVA6ConfigFVecEn", "cvxif" : "CVA6ConfigCvxifEn", "c_ext" : "CVA6ConfigCExtEn", "a_ext" : "CVA6ConfigAExtEn", "b_ext" : "CVA6ConfigBExtEn", "AxiIdWidth" : "CVA6ConfigAxiIdWidth", "AxiAddrWidth" : "CVA6ConfigAxiAddrWidth", "AxiDataWidth" : "CVA6ConfigAxiDataWidth", "iuser_en" : "CVA6ConfigFetchUserEn", "iuser_w" : "CVA6ConfigFetchUserWidth", "duser_en" : "CVA6ConfigDataUserEn", "duser_w" : "CVA6ConfigDataUserWidth", "RenameEn" : "CVA6ConfigRenameEn", "IcacheByteSize" : "CVA6ConfigIcacheByteSize", "IcacheSetAssoc" : "CVA6ConfigIcacheSetAssoc", "IcacheLineWidth" : "CVA6ConfigIcacheLineWidth", "DcacheByteSize" : "CVA6ConfigDcacheByteSize", "DcacheSetAssoc" : "CVA6ConfigDcacheSetAssoc", "DcacheLineWidth" : "CVA6ConfigDcacheLineWidth", "DcacheIdWidth" : "CVA6ConfigDcacheIdWidth", "DcacheIdWidth": "CVA6ConfigDcacheIdWidth", "MemTidWidth": "CVA6ConfigMemTidWidth", "WtDcacheWbufDepth": "CVA6ConfigWtDcacheWbufDepth", "NrCommitPorts" : "CVA6ConfigNrCommitPorts", "NrScoreboardEntries" : "CVA6ConfigNrScoreboardEntries", "FPGAEn" : "CVA6ConfigFPGAEn", "NrLoadPipeRegs" : "CVA6ConfigNrLoadPipeRegs", "NrStorePipeRegs" : "CVA6ConfigNrStorePipeRegs", "InstrTlbEntries" : "CVA6ConfigInstrTlbEntries", "DataTlbEntries" : "CVA6ConfigDataTlbEntries", "RASDepth": "CVA6ConfigRASDepth", "BTBEntries": "CVA6ConfigBTBEntries", "BHTEntries": "CVA6ConfigBHTEntries", "NrPMPEntries": "CVA6ConfigNrPMPEntries", "PerfCounterEn": "CVA6ConfigPerfCounterEn", "DcacheType": "CVA6ConfigDcacheType", "MmuPresent": "CVA6ConfigMmuPresent", "RvfiTrace": "RVFI_PORT", # Ignored parameters "ignored": "CVA6ConfigRvfiTrace", } MapParametersToArgs = {i:k for k, i in MapArgsToParameter.items()} #reverse map def generate_config(argv): parser = setup_parser_config_generator() args = parser.parse_args(argv) Args = vars(args) # give a dictionary of args print("\n[Generating configuration ... ]") print("Default configuration is "+Args['default_config']) print("Make sure to compile your code with this ISA :", Args["isa"], "!") ISA = Args["isa"] if "cv32" in Args['default_config']: gen = "gen32" Args['xlen'] = 32 MABI = "ilp32" else: gen = "gen64" Args['xlen'] = 64 MABI = "lp64" # Read file alllines = [] with open("core/include/" + Args['default_config'] + "_config_pkg.sv", "r") as in_f: alllines = in_f.readlines() # Apply cmdline args to override individual localparam values. for name, value in Args.items(): if name not in ['default_config', 'isa', 'xlen'] and value is not None: param = MapArgsToParameter[name] print("setting", name, "to", value) for i, line in enumerate(alllines): line = re.sub(r"^(\s*localparam\s+"+param+r"\s*=\s*)(.*)(;\s*)$", r"\g<1>"+str(value)+r"\g<3>", line) if isinstance(value, int) and value in [0, 1]: preproc_regexp = r"^(\s*`\s*)(define|undef)(\s+" + param + r"\s*)$" directive = "define" if value == 1 else "undef" line = re.sub(preproc_regexp, r"\g<1>" + directive + r"\g<3>", line) alllines[i] = line # Build Config and warn about localparams which have no matching cmdline option associated with them. for line in alllines: linematch = re.match(r"^(\s*localparam\s+CVA6Config(?P\w*)\s*=\s*)(?P.*)(;\s*)$", line) if linematch: param = 'CVA6Config'+linematch.group('param') value = linematch.group('value') if linematch: try: arg = MapParametersToArgs[param] if value == "CVA6ConfigXlen": Config[arg] = Config['xlen'] elif value == "WB": Config[arg] = 0 elif value == "WT": Config[arg] = 1 else: Config[arg] = int(value) except KeyError: print(f"WARNING: CVA6 configuration parameter '{param}' not supported yet via cmdline args,", "\n\t consider extending script 'config_pkg_generator.py'!") # Write new file with open("core/include/"+gen+"_config_pkg.sv", "w") as out_f: out_f.writelines(alllines) print("[Generating configuration Done]") return [ISA, MABI, gen, Config] # return ISA, MABI, gen (for testharness), Config for cva6.py in core-v-verif if __name__ == "__main__": generate_config(sys.argv[1:])