From 853da681838bc55a2f33db7af47462e244d4ca02 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 8 Dec 2021 07:23:53 -0800 Subject: [PATCH] scripts: Added SVD to Pattern Language converter --- scripts/svd2pat.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 scripts/svd2pat.py diff --git a/scripts/svd2pat.py b/scripts/svd2pat.py new file mode 100644 index 0000000..fd2bb2e --- /dev/null +++ b/scripts/svd2pat.py @@ -0,0 +1,74 @@ +import io +import sys +import xml.etree.ElementTree as ET +import math + +def sortchildrenby(parent, attr): + parent[:] = sorted(parent, key=lambda child: int(child.find(attr).text, 16)) + +# Print usage information +if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} ") + exit() + +# Parse SVD file +svd = ET.parse(sys.argv[1]).getroot() + +# Read processor information +processor_name = svd.find("name").text +register_width = svd.find("width").text +register_type = f"u{register_width}" + +code = "" + +# Add header +code += f"// MMIO Register definition for {processor_name}\n\n" +# Add type definition for register type of correct size +code += f"using reg_t = {register_type};\n\n\n" + +for peripheral in svd.find("peripherals"): + derived = peripheral.attrib.get("derivedFrom") + peripheral_name = peripheral.find("name").text + peripheral_address = int(peripheral.find("baseAddress").text, 16) + + # Generate struct header + code += f"struct {peripheral_name}_t" + + # If register definition has been derived from somewhere else, derive the struct from the other struct + if derived != None: + code += f" : {derived}_t" + + code += " {\n" + + prev_offset = 0 + + registers = peripheral.find("registers") + if registers != None: + sortchildrenby(registers, "addressOffset") + + for register in registers: + register_name = register.find("name").text + register_offset = int(register.find("addressOffset").text, 16) + + # Check if padding has to be inserted + if prev_offset == 0: + pass + elif register_offset - prev_offset > 4: + code += f" padding[{register_offset - prev_offset - 4}];\n" + elif (register_offset - prev_offset != 0) and (register_offset - prev_offset != 4): + print(f"Overlapping register {register_name}!") + exit() + + # Add register variable declaration + code += f" reg_t {register_name}; // 0x{register_offset:03X}\n" + + prev_offset = register_offset + + code += "};\n" + + # Place instance of register type in memory + code += f"{peripheral_name}_t {peripheral_name} @ 0x{peripheral_address:08X};\n\n" + +# Write generated code to a file +with open(sys.argv[1] + ".pat", "w") as file: + file.write(code) \ No newline at end of file