-
Notifications
You must be signed in to change notification settings - Fork 571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to use Ibex with mainline fusesoc #2238
Comments
Ergh, and you're on an ancient version of Edalize so I can't use that. Any pointers to how I can import the RTL source and ignore your Fusesoc flow would be great. |
I've deleted my previous post here and added a new export script. This clones the Ibex repo, runs your version of Fusesoc to export the RTL, and then post processes the RTL to uniquify it. In our case we followed the OT naming convensions so have a bunch of The following Core file enables usage of this exported code base in any other project. I might think about how to combine these two steps at some point if you think it worthwhile. #!/usr/bin/env python3
import os
import sys
import shutil
import tempfile
import subprocess
import fileinput
import re
import argparse
import logging
logger = logging.getLogger(__name__)
def run_command(cmd, cwd=None):
try:
subprocess.run(cmd, cwd=cwd, check=True)
except subprocess.CalledProcessError as e:
logger.info(f"Error running command {' '.join(cmd)}: \n{e}")
sys.exit(1)
def setup_venv(ibex_dir):
run_command([sys.executable, "-m", "venv", "venv"], cwd=ibex_dir)
venv_python = os.path.join(ibex_dir, "venv", "bin", "python")
run_command([venv_python, "-m", "pip", "install", "-U", "pip", "wheel"], cwd=ibex_dir)
run_command([venv_python, "-m", "pip", "install", "-r", "python-requirements.txt"], cwd=ibex_dir)
return venv_python
def find_files(build_dir):
files = []
for root, _, filenames in os.walk(build_dir):
for file in filenames:
if file.endswith(('.sv', '.svh', '.vlt')):
files.append(os.path.join(root, file))
return files
def process_file(src, dest_dir, prefix):
with open(src, 'r') as f:
content = f.read()
filename = os.path.basename(src)
if filename.startswith('prim_') or re.search(r'(module|package)\s+prim_[a-zA-Z0-9_]+', content):
filename = prefix + filename
dest = os.path.join(dest_dir, filename)
shutil.copy2(src, dest)
patterns = [
# Package access needs to be first
(r'\bprim_([a-zA-Z0-9_]+)::([a-zA-Z0-9_]+)', f'{prefix}prim_\\1::\\2'),
# Enum type names
(r'\bprim_([a-zA-Z0-9_]+)_e\b', f'{prefix}prim_\\1_e'),
# Module/interface definitions
(r'\bmodule\s+prim_([a-zA-Z0-9_]+)\b', f'module {prefix}prim_\\1'),
(r'\binterface\s+prim_([a-zA-Z0-9_]+)\b', f'interface {prefix}prim_\\1'),
# General primitive instantiations
(r'\bprim_([a-zA-Z0-9_]+)\s+', f'{prefix}prim_\\1 '),
# Include and import statements
(r'`include\s+"prim_([^"]+)"', f'`include "{prefix}prim_\\1"'),
(r'import\s+prim_([^;]+);', f'import {prefix}prim_\\1;'),
# Package definitions
(r'package\s+prim_([a-zA-Z0-9_]+)\s*;', f'package {prefix}prim_\\1;'),
]
with fileinput.FileInput(dest, inplace=True) as file:
for line in file:
for pattern, replacement in patterns:
line = re.sub(pattern, replacement, line)
print(line, end='')
def export(export_dir: str, prefix: str):
with tempfile.TemporaryDirectory() as temp_dir:
logger.info(f"Created temporary directory: {temp_dir}")
run_command(["git", "clone", "https://github.com/lowrisc/ibex.git"], cwd=temp_dir)
ibex_dir = os.path.join(temp_dir, "ibex")
venv_python = setup_venv(ibex_dir)
run_command([venv_python, "-m", "fusesoc.main", "--cores-root", ".",
"run", "--target=lint", "--setup",
"--build-root", "./build/ibex_out",
"lowrisc:ibex:ibex_top"], cwd=ibex_dir)
os.makedirs(export_dir, exist_ok=True)
build_dir = os.path.join(ibex_dir, "build", "ibex_out", "src")
files = find_files(build_dir)
for file in files:
process_file(file, export_dir, prefix)
logger.info(f"Files exported to {export_dir}")
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"--prefix",
"-p",
default="ot_",
help="Specify a uniquifying prefix to use on all primitive files"
)
parser.add_argument(
"--export-dir",
"-e",
default="export",
help="Specify an export directory"
)
parser.add_argument(
"--clean",
"-c",
action="store_true",
help="Force deletion of the export directory if it exists"
)
parser.add_argument(
"--verbose",
"-v",
action="store_true",
help="Use verbose logging"
)
return parser.parse_args()
def main():
args = get_args()
level = logging.INFO
if args.verbose:
level = logging.DEBUG
logging.basicConfig(format="%(levelname)s: %(message)s", level=level)
if os.path.exists(args.export_dir):
if not args.clean:
logger.error(f"export directory already exists; use --clean or pick another directory")
exit(1)
shutil.rmtree(args.export_dir)
export(args.export_dir, args.prefix)
if __name__ == "__main__":
main() #ibex.core
CAPI=2:
name: lowrisc:export:ibex_top
description: Ibex CPU source code
filesets:
rtl:
files:
- rtl/dv_fcov_macros.svh: {is_include_file: true}
- rtl/ot_prim_assert_yosys_macros.svh: {is_include_file: true}
- rtl/ot_prim_assert_standard_macros.svh: {is_include_file: true}
- rtl/ot_prim_assert_dummy_macros.svh: {is_include_file: true}
- rtl/ot_prim_assert_sec_cm.svh: {is_include_file: true}
- rtl/ot_prim_util_get_scramble_params.svh: {is_include_file: true}
- rtl/ot_prim_util_memload.svh: {is_include_file: true}
- rtl/ot_prim_assert.sv
- rtl/ot_prim_pkg.sv
- rtl/ot_prim_util_pkg.sv
- rtl/ot_prim_secded_pkg.sv
- rtl/ibex_pkg.sv
- rtl/ot_prim_cipher_pkg.sv
- rtl/ot_prim_mubi_pkg.sv
- rtl/ot_prim_count_pkg.sv
- rtl/ot_prim_ram_1p_pkg.sv
- rtl/ot_prim_and2.sv
- rtl/ot_prim_badbit_ram_1p.sv
- rtl/ot_prim_buf.sv
- rtl/ot_prim_clock_gating.sv
- rtl/ot_prim_clock_mux2.sv
- rtl/ot_prim_count.sv
- rtl/ot_prim_flop.sv
- rtl/ot_prim_flop_macros.sv
- rtl/ot_prim_generic_and2.sv
- rtl/ot_prim_generic_buf.sv
- rtl/ot_prim_generic_clock_gating.sv
- rtl/ot_prim_generic_clock_mux2.sv
- rtl/ot_prim_generic_flop.sv
- rtl/ot_prim_generic_ram_1p.sv
- rtl/ot_prim_lfsr.sv
- rtl/ot_prim_mubi12_dec.sv
- rtl/ot_prim_mubi12_sender.sv
- rtl/ot_prim_mubi12_sync.sv
- rtl/ot_prim_mubi16_dec.sv
- rtl/ot_prim_mubi16_sender.sv
- rtl/ot_prim_mubi16_sync.sv
- rtl/ot_prim_mubi20_dec.sv
- rtl/ot_prim_mubi20_sender.sv
- rtl/ot_prim_mubi20_sync.sv
- rtl/ot_prim_mubi24_dec.sv
- rtl/ot_prim_mubi24_sender.sv
- rtl/ot_prim_mubi24_sync.sv
- rtl/ot_prim_mubi28_dec.sv
- rtl/ot_prim_mubi28_sender.sv
- rtl/ot_prim_mubi28_sync.sv
- rtl/ot_prim_mubi32_dec.sv
- rtl/ot_prim_mubi32_sender.sv
- rtl/ot_prim_mubi32_sync.sv
- rtl/ot_prim_mubi4_dec.sv
- rtl/ot_prim_mubi4_sender.sv
- rtl/ot_prim_mubi4_sync.sv
- rtl/ot_prim_mubi8_dec.sv
- rtl/ot_prim_mubi8_sender.sv
- rtl/ot_prim_mubi8_sync.sv
- rtl/ot_prim_onehot_check.sv
- rtl/ot_prim_onehot_enc.sv
- rtl/ot_prim_onehot_mux.sv
- rtl/ot_prim_present.sv
- rtl/ot_prim_prince.sv
- rtl/ot_prim_ram_1p.sv
- rtl/ot_prim_ram_1p_adv.sv
- rtl/ot_prim_ram_1p_scr.sv
- rtl/ot_prim_secded_22_16_dec.sv
- rtl/ot_prim_secded_22_16_enc.sv
- rtl/ot_prim_secded_28_22_dec.sv
- rtl/ot_prim_secded_28_22_enc.sv
- rtl/ot_prim_secded_39_32_dec.sv
- rtl/ot_prim_secded_39_32_enc.sv
- rtl/ot_prim_secded_64_57_dec.sv
- rtl/ot_prim_secded_64_57_enc.sv
- rtl/ot_prim_secded_72_64_dec.sv
- rtl/ot_prim_secded_72_64_enc.sv
- rtl/ot_prim_secded_hamming_22_16_dec.sv
- rtl/ot_prim_secded_hamming_22_16_enc.sv
- rtl/ot_prim_secded_hamming_39_32_dec.sv
- rtl/ot_prim_secded_hamming_39_32_enc.sv
- rtl/ot_prim_secded_hamming_72_64_dec.sv
- rtl/ot_prim_secded_hamming_72_64_enc.sv
- rtl/ot_prim_secded_hamming_76_68_dec.sv
- rtl/ot_prim_secded_hamming_76_68_enc.sv
- rtl/ot_prim_secded_inv_22_16_dec.sv
- rtl/ot_prim_secded_inv_22_16_enc.sv
- rtl/ot_prim_secded_inv_28_22_dec.sv
- rtl/ot_prim_secded_inv_28_22_enc.sv
- rtl/ot_prim_secded_inv_39_32_dec.sv
- rtl/ot_prim_secded_inv_39_32_enc.sv
- rtl/ot_prim_secded_inv_64_57_dec.sv
- rtl/ot_prim_secded_inv_64_57_enc.sv
- rtl/ot_prim_secded_inv_72_64_dec.sv
- rtl/ot_prim_secded_inv_72_64_enc.sv
- rtl/ot_prim_secded_inv_hamming_22_16_dec.sv
- rtl/ot_prim_secded_inv_hamming_22_16_enc.sv
- rtl/ot_prim_secded_inv_hamming_39_32_dec.sv
- rtl/ot_prim_secded_inv_hamming_39_32_enc.sv
- rtl/ot_prim_secded_inv_hamming_72_64_dec.sv
- rtl/ot_prim_secded_inv_hamming_72_64_enc.sv
- rtl/ot_prim_secded_inv_hamming_76_68_dec.sv
- rtl/ot_prim_secded_inv_hamming_76_68_enc.sv
- rtl/ot_prim_subst_perm.sv
- rtl/ot_prim_xilinx_and2.sv
- rtl/ot_prim_xilinx_buf.sv
- rtl/ot_prim_xilinx_clock_gating.sv
- rtl/ot_prim_xilinx_clock_mux2.sv
- rtl/ot_prim_xilinx_flop.sv
- rtl/ibex_pmp.sv
- rtl/ibex_load_store_unit.sv
- rtl/ibex_ex_block.sv
- rtl/ibex_core.sv
- rtl/ibex_multdiv_slow.sv
- rtl/ibex_id_stage.sv
- rtl/ibex_wb_stage.sv
- rtl/ibex_prefetch_buffer.sv
- rtl/ibex_counter.sv
- rtl/ibex_controller.sv
- rtl/ibex_branch_predict.sv
- rtl/ibex_compressed_decoder.sv
- rtl/ibex_fetch_fifo.sv
- rtl/ibex_csr.sv
- rtl/ibex_cs_registers.sv
- rtl/ibex_dummy_instr.sv
- rtl/ibex_alu.sv
- rtl/ibex_if_stage.sv
- rtl/ibex_decoder.sv
- rtl/ibex_multdiv_fast.sv
- rtl/ibex_lockstep.sv
- rtl/ibex_register_file_latch.sv
- rtl/ibex_register_file_fpga.sv
- rtl/ibex_top.sv
- rtl/ibex_register_file_ff.sv
- rtl/ibex_icache.sv
file_type: systemVerilogSource
verilator_waivers:
files:
- rtl/ot_prim_generic_clock_gating.vlt
- rtl/common.vlt
- rtl/ot_prim_onehot_check.vlt
- rtl/ot_prim_cipher.vlt
- rtl/ot_prim_generic_clock_mux2.vlt
- rtl/ot_prim_assert.vlt
- rtl/verilator_waiver.vlt
- rtl/ot_prim_xilinx_clock_gating.vlt
- rtl/verilator_waiver.vlt
- rtl/ot_prim_xilinx_clock_mux2.vlt
- rtl/ot_prim_count.vlt
- rtl/ot_prim_ram_1p_scr.vlt
- rtl/ot_prim_generic_ram_1p.vlt
file_type: vlt
targets:
default:
filesets:
- rtl
- tool_verilator ? (verilator_waivers)
toplevel: ibex_top |
Hi there,
You seem to still be using a custom Fusesoc version that expects a different GAPI structure. The
ot
branch you recommend using is quite a way behind mainline Fusesoc so what are your plans for merging changes and/or pulling the latest changes into your fork?Can you expand on the main differences? Is it just related to your generators or are there additional features?
What would be the workaround for anyone needing to use the latest features of Fusesoc? Can the Ibex source be generated and exported using something like the OT vendoring scripts? Just thinking how I can work around this.
The text was updated successfully, but these errors were encountered: