diff --git a/SoCMakeConfig.cmake b/SoCMakeConfig.cmake index 918af5e..d83ffc6 100644 --- a/SoCMakeConfig.cmake +++ b/SoCMakeConfig.cmake @@ -2,17 +2,25 @@ cmake_minimum_required(VERSION 3.25) set(SoCMake_FOUND TRUE) -include("${CMAKE_CURRENT_LIST_DIR}/cmake/hwip.cmake") +# ==================================== +# ======== Core functions ============ +# ==================================== include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/socmake_graph.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/cmake/hwip.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/subdirectory_search.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/add_subdirs.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/get_all_targets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/print_help.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/graphviz.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/multi_option.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/find_python.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/print_list.cmake") + +# ==================================== +# ======== Additional utilities ====== +# ==================================== include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/copy_rtl_files/copy_rtl_files.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/copy_rtl_files/vhier.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/print_list.cmake") # ==================================== # ======== Simulation ================ @@ -20,7 +28,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/print_list.cmake") # ----- Verilator ------ include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/verilator/verilate.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/verilator/verilate_xml.cmake") # ----- iverilog ------ include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/iverilog/iverilog.cmake") @@ -80,7 +87,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/synth/yosys/yosys_build.cmake") # ==================================== include("${CMAKE_CURRENT_LIST_DIR}/cmake/tmrg/tmrg/tmrg.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/cmake/tmrg/tmrv/tmrv.cmake") # ==================================== # ======== FIRMWARE ================== @@ -89,7 +95,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/tmrg/tmrv/tmrv.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/firmware/fw_utils.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/firmware/add_tests.cmake") include("${CMAKE_CURRENT_LIST_DIR}/cmake/firmware/linker_script/gen_lds.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/cmake/firmware/linker_script/src/lds_props.cmake") set(IBEX_TOOLCHAIN "${CMAKE_CURRENT_LIST_DIR}/cmake/firmware/toolchains/riscv_toolchain.cmake" CACHE INTERNAL "IBEX_TOOLCHAIN") diff --git a/cmake/firmware/linker_script/src/gen_linker_script.py b/cmake/firmware/linker_script/src/gen_linker_script.py deleted file mode 100644 index 6549460..0000000 --- a/cmake/firmware/linker_script/src/gen_linker_script.py +++ /dev/null @@ -1,215 +0,0 @@ -from typing import List -import sys, os -import jinja2 -import argparse - -from systemrdl import RDLCompiler, RDLCompileError, RDLListener, RDLWalker -from systemrdl.node import MemNode, Node - -class RDL2LdsExporter(RDLListener): - """Export SystemRDL to Linker Description Script (LDS). - - Class methods: - - - :func:`enter_Mem` - - :func:`enter_Reg` - - :func:`isSwEx` - - :func:`isSwWr` - - :func:`isBoot` - - :func:`isData` - - :func:`get_sections_prop` - - :func:`getTextMem` - - :func:`getDataMem` - - :func:`getBootMem` - - :func:`getSwAcc` - - :func:`export` - - :func:`process_template`` - """ - def __init__(self): - self.memories = [] - # SystemRDL registers with the UDP linker_symbol set to true - # These register adresses are exposed in the linker script - self.regs = [] - - def enter_Mem(self, node): - if node.get_property("sections", default=False): - self.memories.append(node) - - def enter_Reg(self, node): - if node.get_property("linker_symbol", default=False): - assert not any(reg.inst_name == node.inst_name for reg in self.regs), \ - f"Only one register with linker_symbol property and the same \ - instance name can exist, you probably instantiated \ - {node.parent.orig_type_name} Addrmap multiple times" - - self.regs.append(node) - - def isSwEx(self, mem : MemNode) -> bool: - """Returns True if the section contains executable code.""" - sections = self.get_sections_prop(mem) - if "text" in sections: - return True - return False - - def isSwWr(self, mem : MemNode) -> bool: - """Returns True if section is writable by software.""" - sections = self.get_sections_prop(mem) - if any(item in sections for item in ["data", "bss", "stack"]): - return True - return False - - def isText(self, mem : MemNode) -> bool: - """Returns True if section is contains the bootloader.""" - sections = self.get_sections_prop(mem) - if "text" in sections: - return True - return False - - def isBoot(self, mem : MemNode) -> bool: - """Returns True if section is contains the bootloader.""" - sections = self.get_sections_prop(mem) - if "boot" in sections: - return True - return False - - def isData(self, mem : MemNode) -> bool: - """Returns True if section contains data.""" - sections = self.get_sections_prop(mem) - if "data" in sections: - return True - return False - - def get_sections_prop(self, m : MemNode) -> List[str]: - """Returns a list of string corresponding to the section properties.""" - sections = m.get_property('sections').split('|') - for s in sections: - assert_m = f"Illegal property for sections: {s} of memory: {m.inst_name} in addrmap: {m.parent.inst_name}" - assert s in ['text', 'data', 'boot'], assert_m - - return sections - - def getTextMem(self, mems: List[MemNode]) -> MemNode: - """Returns the program/instruction/text MemNode.""" - prog_mems = [] - for m in mems: - if self.isSwEx(m) and self.isText(m): - prog_mems.append(m) - assert len(prog_mems) == 1, f"Exactly 1 memory with program memory is allowed and required {prog_mems}" # TODO - - return prog_mems[0] - - def getDataMem(self, mems: List[MemNode]) -> MemNode: - """Returns the data MemNode.""" - data_mems = [] - for m in mems: - if self.isData(m): - data_mems.append(m) - assert len(data_mems) == 1, f"Exactly 1 memory with program memory is allowed and required {data_mems}" # TODO - - return data_mems[0] - - def getBootMem(self, mems: List[MemNode]) -> "MemNode | None": - """Returns the boot MemNode.""" - boot_mems = [] - for m in mems: - if self.isBoot(m): - boot_mems.append(m) - assert len(boot_mems) <= 1, f"No more than 1 boot memory is allowed {boot_mems}" # TODO - - return boot_mems[0] if len(boot_mems) > 0 else None - - def getSwAcc(self, mem : MemNode) -> str: - """Returns the software access rights to the MemNode.""" - out = "r" - if self.isSwWr(mem): - out = out + "w" - if self.isSwEx(mem): - out = out + "x" - return out - - def export(self, - node: Node, - outfile : str, - debug : bool = True, - ): - - context = {'mems' : self.memories, - 'debug' : debug, - 'regs' : self.regs - } - - text = self.process_template(context, "linker.lds.j2") - - with open(outfile, 'w') as f: - f.write(text) - - def process_template(self, context : dict, template : str) -> str: - - env = jinja2.Environment( - loader=jinja2.FileSystemLoader('%s/template/' % os.path.dirname(__file__)), - trim_blocks=True, - lstrip_blocks=True) - - env.filters.update({ - 'zip' : zip, - 'int' : int, - 'isSwWr' : self.isSwWr, - 'isSwEx' : self.isSwEx, - 'getSwAcc' : self.getSwAcc, - 'getTextMem' : self.getTextMem, - 'getBootMem' : self.getBootMem, - 'getDataMem' : self.getDataMem, - }) - - res = env.get_template(template).render(context) - return res - - -def main(): - parser = argparse.ArgumentParser( - prog='LDS generator', - description='Generates a linker script from RDL files') - - parser.add_argument('--rdlfiles', nargs="+", help='RDL input files') - parser.add_argument('--outfile', required=True, help='Output lds file') - parser.add_argument('--debug', default=False, action="store_true", help='Include debug section in the lds or discard it') - parser.add_argument('-p', '--param', nargs='+', help="Parameter to overwrite on top RDL module in the format 'PARAM=VALUE'") - - args = parser.parse_args() - - overwritten_params_dict = {} - if args.param is not None: - for param in args.param: - key, value = param.split('=') - overwritten_params_dict[key] = int(value) - - rdlc = RDLCompiler() - - try: - for input_file in args.rdlfiles: - rdlc.compile_file(input_file) - root = rdlc.elaborate(parameters=overwritten_params_dict) - except RDLCompileError: - sys.exit(1) - - top_gen = root.children(unroll=True) - # Is this really needed? - top = None - for top in top_gen: - top = top - assert top is not None - - walker = RDLWalker(unroll=True) - rdl2lds = RDL2LdsExporter() - walker.walk(top, rdl2lds) - - rdl2lds.export( - node=top, - outfile=args.outfile, - debug=args.debug, - ) - - -if __name__ == "__main__": - main() - diff --git a/cmake/firmware/linker_script/src/lds_props.cmake b/cmake/firmware/linker_script/src/lds_props.cmake deleted file mode 100644 index 1bfa59f..0000000 --- a/cmake/firmware/linker_script/src/lds_props.cmake +++ /dev/null @@ -1,13 +0,0 @@ -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/../../../hwip.cmake") - -add_ip(base - VENDOR cern - LIBRARY ldsgen - VERSION 0.0.1 - ) -ip_sources(${IP} SYSTEMRDL - ${CMAKE_CURRENT_LIST_DIR}/lds_props.rdl - ) - diff --git a/cmake/firmware/linker_script/src/lds_props.rdl b/cmake/firmware/linker_script/src/lds_props.rdl deleted file mode 100644 index 6dd847f..0000000 --- a/cmake/firmware/linker_script/src/lds_props.rdl +++ /dev/null @@ -1,11 +0,0 @@ -property sections { - type = string; - component = mem; -}; - -// This property generate a symbol with the register -// absolute address in the linker script -property linker_symbol { // MOve to LDS_gen - type = boolean; - component = reg; -}; diff --git a/cmake/firmware/linker_script/src/template/linker.lds.j2 b/cmake/firmware/linker_script/src/template/linker.lds.j2 deleted file mode 100644 index 5a55d6c..0000000 --- a/cmake/firmware/linker_script/src/template/linker.lds.j2 +++ /dev/null @@ -1,267 +0,0 @@ -/* Copyright (c) 2024 CERN */ -/* SPDX-License-Identifier: Apache-2.0 */ - -OUTPUT_FORMAT("elf32-littleriscv") -OUTPUT_ARCH(riscv) - -ENTRY(_entry) - -MEMORY { -{% for m in mems %} - {{ m.parent.inst_name }} ({{ m|getSwAcc }}): ORIGIN = 0x{{ '%08x' % m.absolute_address }}, LENGTH = 0x{{ '%08x' % m.size }} -{% endfor %} -} - -{% set prog_mem = mems|getTextMem %} -{% set boot_mem = mems|getBootMem %} -{% set data_mem = mems|getDataMem %} - -{% for reg in regs %} -PROVIDE({{reg.inst_name}} = 0x{{ '%08x' % reg.absolute_address }}); -{% endfor %} - -SECTIONS -{ - /* we want a fixed boot point */ - PROVIDE(__boot_address = ORIGIN( {{ boot_mem.parent.inst_name }} )); - - {% if boot_mem is not none %} - .bootloader : { - *bootloader.S.o*(*); - *bootloader.cpp.o*(*); - . = ALIGN(4); - } > {{ boot_mem.parent.inst_name }} - {% endif %} - - /* we want a fixed entry point */ - PROVIDE(__entry_address = ORIGIN( {{ prog_mem.parent.inst_name }} ) + 0x180); - - /* stack and heap related settings */ - __stack_size = DEFINED(__stack_size) ? __stack_size : 0x800; - PROVIDE(__stack_size = __stack_size); - __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; - - /***************************************/ - /* PROGRAM / TEXT / READ-ONLY SECTIONS */ - /***************************************/ - - /* interrupt vectors */ - .vectors (ORIGIN( {{ prog_mem.parent.inst_name }} )): - { - PROVIDE(__vector_start = .); - KEEP(*(.vectors)); - } > {{ prog_mem.parent.inst_name }} - - /* crt0 init code */ - .init (__entry_address): - { - /* The _enter symbol is placed in the .text.entry section - * and must be placed at the beginning of the program */ - KEEP (*(.text.entry)) - KEEP (*(SORT_NONE(.init))) - /* Align on 4 bytes to avoid errors during hex generation */ - FILL(0xDEAD) - . = ALIGN(4); - } > {{ prog_mem.parent.inst_name }} - - /* not used by RISC-V */ - .fini : - { - KEEP (*(SORT_NONE(.fini))) - /* Align on 4 bytes to avoid errors during hex generation */ - FILL(0xDEAD) - . = ALIGN(4); - } > {{ prog_mem.parent.inst_name }} - - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - /* Keep interrupt handlers close to vector table */ - *(.text.vecs*) - *(.text .text.*) - *(.gnu.linkonce.t.*) - } > {{ prog_mem.parent.inst_name }} - - /*****************/ - /* DATA SECTIONS */ - /*****************/ - - /* initialization and termination routines */ - .preinit_array : ALIGN(8) - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } > {{ data_mem.parent.inst_name }} - - .init_array : ALIGN(8) - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } > {{ data_mem.parent.inst_name }} - - .fini_array : ALIGN(8) - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } > {{ data_mem.parent.inst_name }} - - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } > {{ data_mem.parent.inst_name }} - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } > {{ data_mem.parent.inst_name }} - - .rodata : { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } > {{ data_mem.parent.inst_name }} - - /* data sections for initalized data */ - .data : ALIGN(8) - { - *(.data .data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - /* The compiler uses this to access data in the .sdata, .data, .sbss and .bss - sections with fewer instructions (relaxation). This reduces code size. - */ - PROVIDE( __global_pointer$ = . + 0x800 ); - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - } > {{ data_mem.parent.inst_name }} - - /* Thread Local Storage sections */ - .tdata : ALIGN(8) - { - PROVIDE_HIDDEN ( __tdata_start = . ); - *(.tdata .tdata.*) - *(.gnu.linkonce.td.*) - } > {{ data_mem.parent.inst_name }} - - PROVIDE ( __edata = . ); - - /* zero initialized sections */ - .tbss : ALIGN(8) - { - PROVIDE( __bss_start = . ); - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - } > {{ data_mem.parent.inst_name }} - - .bss (NOLOAD): ALIGN(8) { - *(.sbss*) - *(.gnu.linkonce.sb.*) - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - PROVIDE( __bss_end = . ); - } > {{ data_mem.parent.inst_name }} - - /* second level sbss and sdata, not needed for now */ - /* .sdata2 : {*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)} */ - /* .sbss2 : {*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } */ - - .stack (NOLOAD) : ALIGN(16) /* This is a requirement of the ABI */ - { - PROVIDE( __stack_start = . ); - . = __stack_size; - PROVIDE( _sp = . ); - PROVIDE( __stack_end = . ); - } > {{ data_mem.parent.inst_name }} - - .heap (NOLOAD) : ALIGN(8) - { - PROVIDE( __end = . ); - PROVIDE( __heap_start = . ); - . = __heap_size; - PROVIDE( __heap_end = . ); - } > {{ data_mem.parent.inst_name }} - - /******************/ - /* DEBUG SECTIONS */ - /******************/ - - {% if debug %} - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } > {{ data_mem.parent.inst_name }} - .stabstr 0 : { *(.stabstr) } > {{ data_mem.parent.inst_name }} - .stab.excl 0 : { *(.stab.excl) } > {{ data_mem.parent.inst_name }} - .stab.exclstr 0 : { *(.stab.exclstr) } > {{ data_mem.parent.inst_name }} - .stab.index 0 : { *(.stab.index) } > {{ data_mem.parent.inst_name }} - .stab.indexstr 0 : { *(.stab.indexstr) } > {{ data_mem.parent.inst_name }} - .comment 0 : { *(.comment) } > {{ data_mem.parent.inst_name }} - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } > {{ data_mem.parent.inst_name }} - .line 0 : { *(.line) } > {{ data_mem.parent.inst_name }} - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } > {{ data_mem.parent.inst_name }} - .debug_sfnames 0 : { *(.debug_sfnames) } > {{ data_mem.parent.inst_name }} - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } > {{ data_mem.parent.inst_name }} - .debug_pubnames 0 : { *(.debug_pubnames) } > {{ data_mem.parent.inst_name }} - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } > {{ data_mem.parent.inst_name }} - .debug_abbrev 0 : { *(.debug_abbrev) } > {{ data_mem.parent.inst_name }} - .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) } > {{ data_mem.parent.inst_name }} - .debug_frame 0 : { *(.debug_frame) } > {{ data_mem.parent.inst_name }} - .debug_str 0 : { *(.debug_str) } > {{ data_mem.parent.inst_name }} - .debug_loc 0 : { *(.debug_loc) } > {{ data_mem.parent.inst_name }} - .debug_macinfo 0 : { *(.debug_macinfo) } > {{ data_mem.parent.inst_name }} - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } > {{ data_mem.parent.inst_name }} - .debug_funcnames 0 : { *(.debug_funcnames) } > {{ data_mem.parent.inst_name }} - .debug_typenames 0 : { *(.debug_typenames) } > {{ data_mem.parent.inst_name }} - .debug_varnames 0 : { *(.debug_varnames) } > {{ data_mem.parent.inst_name }} - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } > {{ data_mem.parent.inst_name }} - .debug_ranges 0 : { *(.debug_ranges) } > {{ data_mem.parent.inst_name }} - /* DWARF Extension. */ - .debug_macro 0 : { *(.debug_macro) } > {{ data_mem.parent.inst_name }} - .debug_addr 0 : { *(.debug_addr) } > {{ data_mem.parent.inst_name }} - .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } > {{ data_mem.parent.inst_name }} - {% endif %} - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(*) } > {{ data_mem.parent.inst_name }} - -}; - diff --git a/cmake/peakrdl/peakrdl_socgen/common/socgen_props.cmake b/cmake/peakrdl/peakrdl_socgen/common/socgen_props.cmake deleted file mode 100644 index 4228d6a..0000000 --- a/cmake/peakrdl/peakrdl_socgen/common/socgen_props.cmake +++ /dev/null @@ -1,17 +0,0 @@ -include_guard(GLOBAL) - -include("${CMAKE_CURRENT_LIST_DIR}/../../../hwip.cmake") - -add_ip(base - VENDOR cern - LIBRARY socgen - VERSION 0.0.5 -) - -ip_sources(${IP} SYSTEMRDL_SOCGEN - ${CMAKE_CURRENT_LIST_DIR}/socgen_props.rdl - ) - -ip_sources(${IP} SYSTEMRDL - ${CMAKE_CURRENT_LIST_DIR}/socgen_props.rdl - ) diff --git a/cmake/peakrdl/peakrdl_socgen/common/socgen_props.rdl b/cmake/peakrdl/peakrdl_socgen/common/socgen_props.rdl deleted file mode 100644 index 6f838f2..0000000 --- a/cmake/peakrdl/peakrdl_socgen/common/socgen_props.rdl +++ /dev/null @@ -1,156 +0,0 @@ -`ifndef COMMON_RDL -`define COMMON_RDL - -// input or output property is needed to be detected by socgen -property output { - type = boolean; - component = signal; -}; - -property input { - type = boolean; - component = signal; -}; - -property clock { - type = boolean; - component = signal; -}; - -// reset property is a a built-in SystemRDL property but not for signals -property reset_signal { - type = boolean; - component = signal; -}; - -property datatype { - type = string; - component = signal; -}; - -property master { - type = boolean; - component = addrmap; -}; - -property subsystem { - type = boolean; - component = addrmap; -}; - -property interconnect { - type = boolean; - component = addrmap; -}; - -property adapter { - type = boolean; - component = addrmap; -}; - -property connections { - type = string[]; - component = addrmap; -}; - -property path { - type = string; - component = signal; -}; - -struct intc { - string name; - string slv_ports[]; - string mst_ports[]; -}; - -property intc_l { - type = intc[]; - component = addrmap; -}; - -// desc = "Slave select signal, should not be shared between slaves"; -property ss { - type = boolean; - component = signal; -}; - -property interconnect_name { - type = string; - component = addrmap; -}; - -property mosi { - type = boolean; - component = signal; -}; - -property miso { - type = boolean; - component = signal; -}; - -signal clk { - input; - clock; - signalwidth=1; - desc = "Input clock"; -}; - -signal rstn { - input; - reset_signal; - signalwidth=1; - desc = "Input reset, active low"; - activelow = true; -}; - -signal rst { - input; - reset_signal; - signalwidth=1; - desc = "Input reset, active high"; - activehigh = true; -}; - -property intf { - type = boolean; - component = addrmap; -}; - -property n_array { - type = longint unsigned; - component = addrmap; -}; - -enum Modport { - slave = 0; - master = 1; -}; - -struct base_intf{ - Modport modport; - string prefix; - boolean cap; -}; - -struct data_intf : base_intf { - longint unsigned DATA_WIDTH; - -}; - -struct addr_intf : data_intf { - longint unsigned ADDR_WIDTH; -}; - -property intf_inst{ - component = addrmap; - type = base_intf; -}; - -property ifports { - component = addrmap; - type = base_intf[]; -}; - -`endif diff --git a/cmake/peakrdl/peakrdl_socgen/peakrdl_socgen.cmake b/cmake/peakrdl/peakrdl_socgen/peakrdl_socgen.cmake index bd3b55e..e5a3d0d 100644 --- a/cmake/peakrdl/peakrdl_socgen/peakrdl_socgen.cmake +++ b/cmake/peakrdl/peakrdl_socgen/peakrdl_socgen.cmake @@ -183,5 +183,3 @@ function(peakrdl_socgen IP_LIB) add_dependencies(${IP_LIB} ${IP_LIB}_socgen) endfunction() - -include("${CMAKE_CURRENT_LIST_DIR}/common/socgen_props.cmake") diff --git a/cmake/sim/verilator/scripts/parse_vlt_xml.py b/cmake/sim/verilator/scripts/parse_vlt_xml.py deleted file mode 100644 index 376bb6a..0000000 --- a/cmake/sim/verilator/scripts/parse_vlt_xml.py +++ /dev/null @@ -1,201 +0,0 @@ -import argparse -from re import split -# import xml.etree.ElementTree as ET -# import lxml.etree.ElementTree as ET -from lxml import etree as ET -import os, re -from collections import defaultdict -import jinja2 - -def path_to_module(node): - if node.tag == 'module': - return [node] - - # path.append(node) - # if node.tag == 'begin': - # if node.get('name') is not None: - # path.extend(node) - path = path_to_module(node.getparent()) - path.append(node) - return path - # return path - # else: - # if parent.tag == 'begin': - # if parent.get('name') is not None: - - -def append_reg(regs_d : dict, reg_varref, module, attrib='name'): - path = path_to_module(reg_varref) - str_path = "" - for p in path: - if p.tag == 'module': - str_path += p.get('name') - - if p.tag == 'begin': - if p.get('name') is not None: - str_path += "." + p.get('name') - if p.tag == 'varref': - str_path += "." + p.get('name') - - try: - if reg_varref.get('name') not in regs_d[module.get(attrib)]: - regs_d[module.get(attrib)].append(reg_varref.get('name')) - except KeyError: - regs_d[module.get(attrib)] = [reg_varref.get('name')] - - return regs_d - -def get_reg_recursive(node): - if node.tag == "varref": - return node - elif node.tag == "arraysel" or node.tag == "sel" or node.tag == "structsel": - return get_reg_recursive(node[0]) - - assert False, f"Unexpected {node.tag}, only supported is varref, arraysel, sel for now, review the script to add suport for {node.tag} on left hand side of non blocking assignment" - -def process_h_tmpl(context : dict) -> str: - - env = jinja2.Environment( - loader=jinja2.FileSystemLoader('%s/' % os.path.dirname(__file__)), - trim_blocks=True, - lstrip_blocks=True) - - res = env.get_template("seq_vpi_handles.j2").render(context) - return res - - -def main( - xml_file : str, - outdir : str, - prefix : "str | None", - vlt : bool, - reg_list : bool, - reg_h : bool, - ): - tree = ET.parse(xml_file) - root = tree.getroot() - - # root = modify_path_to_generate_blocks(root) - # get reg names - regs = {} - regs_origname = {} - for module in root.findall('.//module'): - for assigndly in module.findall('.//assigndly'): - lhs = assigndly[1] - reg = get_reg_recursive(lhs) - regs = append_reg(regs, reg, module) - regs_origname = append_reg(regs_origname, reg, module, attrib='origName') - - - module_paths = {} - for module in root.findall('.//module'): - if module.get('name') in regs: - for cell in root.findall('.//cell'): - if module.get('name') == cell.get('submodname'): - try: - if module.get('name') not in module_paths[module.get('name')]: - module_paths[module.get('name')].append(cell.get('hier')) - except KeyError: - module_paths[module.get('name')] = [cell.get('hier')] - - reg_paths = [] - for k,v in module_paths.items(): - for val in v: - for reg in regs[k]: - path = val + "." + reg - path = path.replace('[', '__BRA__') - path = path.replace(']', '__KET__') - reg_paths.append(path) - - if prefix == None: - xml_basename = os.path.basename(xml_file) - prefix = os.path.splitext(xml_basename)[0] - - os.makedirs(outdir, exist_ok=True) - - if vlt: - outfile = os.path.abspath(os.path.join(outdir, prefix + "_regpublic.vlt")) - with open(outfile, "w") as f: - f.write("`verilator_config\n\n") - for k, v in regs_origname.items(): - for sig in v: - sig = sig.split('.')[-1] - f.write(f'public_flat_rw -module "{k}" -var "{sig}"\n') - f.write("\n") - - if reg_list: - outfile = os.path.abspath(os.path.join(outdir, prefix + "_reglist.txt")) - with open(outfile, "w") as f: - for p in reg_paths: - f.write(f'{p}\n') - - if reg_h: - outfile = os.path.abspath(os.path.join(outdir, prefix + "_seq_vpi_handles.h")) - with open(outfile, "w") as f: - out = process_h_tmpl({'paths' : reg_paths}) - f.write(out) - - -def modify_path_to_generate_blocks(root): - blocks = {} - for begin in root.findall('.//begin'): - blocks[begin.get('name')] = [] - - # print("------------------", begin.attrib) - for inst in begin.findall('.//instance'): - blocks[begin.get('name')].append({'loc': inst.get('loc'), 'defName':inst.get('defName')}) - blocks = {key: value for key, value in blocks.items() if value != []} - - key_arrays = defaultdict(list) # Array generate blocks - keys = {} # Normal generate blocks - for k, v in blocks.items(): - pattern = r'(\w+)\[(\d+)\]' - match = re.match(pattern, k) - if match is not None: - key_arrays[match[1]].append(v) - else: - keys[k] = v - - for k, v in key_arrays.items(): # Verify values are the same for keys list of values - assert all(x == v[0] for x in v) - for val in v[0]: - defname = val['defName'] - loc = val['loc'] - # print(defname) - cells = root.findall(f".//cell[@submodname='{defname}'][@loc='{loc}']") - for cnt, cell in enumerate(cells): - path = cell.get('hier').split('.') - path.insert(-1, k + f"[{cnt}]") - path = '.'.join(path) - cell.set('hier', path) - - for k, v in keys.items(): - for val in v: - for cell in root.findall('.//cell'): - if cell.get('submodname') == val['defName'] and cell.get('loc') == val['loc']: - path = cell.get('hier').split('.') - path.insert(-1, k) - path = '.'.join(path) - cell.set('hier', path) - return root - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - prog='Verilator sequential nets XML parser', - description='Parses Verilator XML file generated with --xml-only command line option, and finds all the non blocking assignment left hand side nets. Generates multiple formats from the list: .vlt for verilator public, ...') - - parser.add_argument('xmlfile', help='XML input file') - parser.add_argument('outdir', help='Generated files output dir') - parser.add_argument('--prefix', type=str, help='Prefix of the output files _regpublic.vlt') - - parser.add_argument('--vlt', action="store_true", help='Generate vlt verilator config file') - parser.add_argument('--reg-list', action="store_true", help='Generate file with list of register paths') - parser.add_argument('--reg-h', action="store_true", help='Generate file with list of register paths') - - args = parser.parse_args() - main(args.xmlfile, args.outdir, args.prefix, args.vlt, args.reg_list, args.reg_h) - - - - - diff --git a/cmake/sim/verilator/scripts/seq_vpi_handles.j2 b/cmake/sim/verilator/scripts/seq_vpi_handles.j2 deleted file mode 100644 index a2ec35a..0000000 --- a/cmake/sim/verilator/scripts/seq_vpi_handles.j2 +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __SEQ_VPI_HANDLES -#define __SEQ_VPI_HANDLES - -#include -#include -#include -#include "vpi_signal.h" - -void append_vpi_signal(std::string path, std::vector &vec){ - try{ - vec.push_back(vpi_signal(path)); - } catch (VpiSignalNotExist &e){ - std::cout << "Cannot find VPI signal " << path << "\n"; - } -} -std::vector create_seq_vpi_handles(std::string root){ - std::vector vec; - if(root.back() != '.') - root.push_back('.'); - - {% for p in paths %} - append_vpi_signal(root + "{{ p }}", vec); // {{ loop.index-1 }} - - {% endfor %} - return vec; -} - -#endif - diff --git a/cmake/sim/verilator/verilate_xml.cmake b/cmake/sim/verilator/verilate_xml.cmake deleted file mode 100644 index 2483b61..0000000 --- a/cmake/sim/verilator/verilate_xml.cmake +++ /dev/null @@ -1,120 +0,0 @@ -include_guard(GLOBAL) - -function(verilate_xml IP_LIB) - set(OPTIONS "GEN_REGPUBLIC") - set(ONE_PARAM_ARGS "PREFIX;OUTDIR;TOP_MODULE") - set(MULTI_PARAM_ARGS "VERILATOR_ARGS") - - cmake_parse_arguments(ARG "${OPTIONS}" - "${ONE_PARAM_ARGS}" - "${MULTI_PARAM_ARGS}" - ${ARGN}) - - if(ARG_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}") - endif() - - include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../hwip.cmake") - include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../utils/find_python.cmake") - - # frpm hwip.cmake. deferences full name of ip - ip_assume_last(IP_LIB ${IP_LIB}) - - # get binary dir location - get_target_property(BINARY_DIR ${IP_LIB} BINARY_DIR) - - if(NOT ARG_OUTDIR) - set(OUTDIR ${BINARY_DIR}/verilate_xml) - else() - set(OUTDIR ${ARG_OUTDIR}) - endif() - file(MAKE_DIRECTORY ${OUTDIR}) - - get_ip_include_directories(INCLUDE_DIRS ${IP_LIB} SYSTEMVERILOG VERILOG) - - foreach(INC_DIR ${INCLUDE_DIRS}) - list(APPEND INC_DIRS_ARG -I${INC_DIR}) - endforeach() - - if(ARG_TOP_MODULE) - set(TOP_MODULE ${ARG_TOP_MODULE}) - else() - get_target_property(TOP_MODULE ${IP_LIB} IP_NAME) - endif() - - get_ip_property(VERILATOR_ARGS ${IP_LIB} VERILATOR_ARGS) - list(APPEND VERILATOR_ARGS ${ARG_VERILATOR_ARGS}) - - get_ip_sources(SOURCES ${IP_LIB} SYSTEMVERILOG VERILOG) - list(PREPEND SOURCES ${V_SOURCES}) - - get_ip_compile_definitions(COMP_DEFS ${IP_LIB} SYSTEMVERILOG VERILOG VHDL) - foreach(def ${COMP_DEFS}) - list(APPEND VERILATOR_ARGS -D${def}) - endforeach() - - if(NOT SOURCES) - message(FATAL_ERROR "Verilate function needs at least one VERILOG or SYSTEMVERILOG source added to the IP") - endif() - - set(XML_FILE ${OUTDIR}/${IP_LIB}.xml) - - # taken from verilator github cmake file - find_program(VERILATOR_BIN NAMES verilator_bin - HINTS ${VERISC_HOME}/open/* $ENV{VERISC_HOME}/open/* ${VERILATOR_HOME}/bin ENV VERILATOR_HOME - NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - - set(STAMP_FILE "${OUTDIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}.stamp") - - add_custom_command( - OUTPUT ${XML_FILE} ${STAMP_FILE} - COMMAND ${VERILATOR_BIN} --xml-output ${XML_FILE} - ${SOURCES} - ${INC_DIRS_ARG} - ${VERILATOR_ARGS} - --top-module ${TOP_MODULE} - COMMAND touch ${STAMP_FILE} - DEPENDS ${SOURCES} - ) - - add_custom_target( - ${IP_LIB}_verilate_xml - DEPENDS ${XML_FILE} ${STAMP_FILE} ${IP_LIB} - ) - - if(ARG_GEN_REGPUBLIC) - set(VLT_CFG_FILE ${OUTDIR}/${IP_LIB}_regpublic.vlt) - set(REG_LIST ${OUTDIR}/${IP_LIB}_reglist.txt) - set(REG_H_FILE ${OUTDIR}/${IP_LIB}_seq_vpi_handles.h) - set(STAMP_FILE "${BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}.stamp") - - - find_python3() # sets Python3_EXECUTABLE - add_custom_command( - OUTPUT ${VLT_CFG_FILE} ${REG_LIST} ${REG_H_FILE} ${STAMP_FILE} - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/scripts/parse_vlt_xml.py - ${XML_FILE} - ${OUTDIR} - --prefix ${IP_LIB} - --vlt --reg-list --reg-h - COMMAND touch ${STAMP_FILE} - DEPENDS ${IP_LIB}_verilate_xml ${XML_FILE} - ) - - add_custom_target( - ${IP_LIB}_verilate_xml_regpublic - DEPENDS ${VLT_CFG_FILE} ${REG_LIST} ${REG_H_FILE} ${STAMP_FILE} ${XML_FILE} - ) - - set_property(TARGET ${IP_LIB}_verilate_xml_regpublic PROPERTY VPIREG_LIST ${REG_LIST}) - # add vlt file to sources list - ip_sources(${IP_LIB} SYSTEMVERILOG ${VLT_CFG_FILE}) - target_sources(${IP_LIB} INTERFACE - FILE_SET HEADERS - BASE_DIRS "${OUTDIR}" - FILES ${REG_H_FILE} - ) - - endif() - -endfunction() diff --git a/cmake/tmrg/tmrv/tmrv.cmake b/cmake/tmrg/tmrv/tmrv.cmake deleted file mode 100644 index 33d09e3..0000000 --- a/cmake/tmrg/tmrv/tmrv.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# TODO iterate over linked libraries and replace SYSTEMVERILOG_SOURCES with VERILOG_SOURCES instead -include_guard(GLOBAL) - -function(tmrv IP_LIB) - cmake_parse_arguments(ARG "REPLACE" "OUTDIR" "" ${ARGN}) - if(ARG_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}") - endif() - - include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../hwip.cmake") - include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../utils/find_python.cmake") - find_python3() - - ip_assume_last(IP_LIB ${IP_LIB}) - get_target_property(BINARY_DIR ${IP_LIB} BINARY_DIR) - - if(NOT ARG_OUTDIR) - set(OUTDIR ${BINARY_DIR}/tmrv) - else() - set(OUTDIR ${ARG_OUTDIR}) - endif() - execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTDIR}) - - get_ip_sources(SOURCES ${IP_LIB} SYSTEMVERILOG VERILOG) - list(PREPEND SOURCES ${V_SOURCES}) - list(REMOVE_DUPLICATES SOURCES) - - get_ip_include_directories(INCDIRS ${IP_LIB} VERILOG SYSTEMVERILOG) - foreach(dir ${INCDIRS}) - list(APPEND INCDIR_ARG -I${dir}) - endforeach() - - # TODO get verilog defines - - foreach(v ${SOURCES}) - get_filename_component(base_name ${v} NAME_WE) - get_filename_component(ext ${v} EXT) - list(APPEND V_GEN ${OUTDIR}/${base_name}Voted${ext}) - endforeach() - - set_source_files_properties(${V_GEN} PROPERTIES GENERATED TRUE) - - set(STAMP_FILE "${BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}.stamp") - add_custom_command( - OUTPUT ${STAMP_FILE} ${V_GEN} - COMMAND ${Python3_EXECUTABLE} -m tmrv - ${SOURCES} - -o ${OUTDIR} - - COMMAND touch ${STAMP_FILE} - DEPENDS ${SOURCES} - COMMENT "Running ${CMAKE_CURRENT_FUNCTION} on ${IP_LIB}" - ) - - add_custom_target( - ${IP_LIB}_${CMAKE_CURRENT_FUNCTION} - DEPENDS ${STAMP_FILE} ${SOURCES} ${V_GEN} - ) - - if(ARG_REPLACE) - set_property(TARGET ${IP_LIB} PROPERTY VERILOG_SOURCES ${V_GEN}) - set_property(TARGET ${IP_LIB} PROPERTY SYSTEMVERILOG_SOURCES "") - add_dependencies(${IP_LIB} ${IP_LIB}_${CMAKE_CURRENT_FUNCTION}) - endif() - -endfunction() - - - - -