今天来看一个具体实例,上一篇传送门:python SystemRDL 包介绍_Bug_Killer_Master的博客-CSDN博客
通常来说,我们验证过程用到的情况大多都是需要提取reg field的路径以及reset 值等信息,所以比较常见的一种方法就是先把rdl compile+elaborate 成Node信息,然后输出成json文件,因为Python 在其标准库中有一个优秀的 JSON 序列化程序。这意味着我们需要做的就是将寄存器模型中的信息提取为原始数据类型,这些数据类型可以很好地转换为JSON。当然我们需要的所有信息都可以放到json文件中以便我们进一步使用。
下面就是转成json的例子,首先假设我们的json文件里面各个层级的信息如下:
1. convert_field
def convert_field(rdlc: RDLCompiler, obj: node.FieldNode) -> dict:json_obj = dict()json_obj['type'] = 'field'json_obj['inst_name'] = obj.inst_namejson_obj['lsb'] = obj.lsbjson_obj['msb'] = obj.msbjson_obj['reset'] = obj.get_property('reset')json_obj['sw_access'] = obj.get_property('sw').namereturn json_obj
FieldNode的所有property参考链接:SystemRDL Property Reference — SystemRDL Compiler documentation (systemrdl-compiler.readthedocs.io)
2. convert_reg
def convert_reg(rdlc: RDLCompiler, obj: node.RegNode) -> dict:if obj.is_array:# Use the RDL Compiler message system to print an error# fatal() raises RDLCompileErrorrdlc.msg.fatal("JSON export does not support arrays",obj.inst.inst_src_ref)# Convert information about the registerjson_obj = dict()json_obj['type'] = 'reg'json_obj['inst_name'] = obj.inst_namejson_obj['addr_offset'] = obj.address_offset# Iterate over all the fields in this reg and convert themjson_obj['children'] = []for field in obj.fields():json_field = convert_field(rdlc, field)json_obj['children'].append(json_field)return json_obj
RegNode的所有property参考链接:
3.covert_addrmap_or_regfile
def convert_addrmap_or_regfile(rdlc: RDLCompiler, obj: Union[node.AddrmapNode, node.RegfileNode]) -> dict:if obj.is_array:rdlc.msg.fatal("JSON export does not support arrays",obj.inst.inst_src_ref)json_obj = dict()if isinstance(obj, node.AddrmapNode):json_obj['type'] = 'addrmap'elif isinstance(obj, node.RegfileNode):json_obj['type'] = 'regfile'else:raise RuntimeErrorjson_obj['inst_name'] = obj.inst_namejson_obj['addr_offset'] = obj.address_offsetjson_obj['children'] = []for child in obj.children():if isinstance(child, (node.AddrmapNode, node.RegfileNode)):json_child = convert_addrmap_or_regfile(rdlc, child)elif isinstance(child, node.RegNode):json_child = convert_reg(rdlc, child)json_obj['children'].append(json_child)return json_obj
4.json dump
def convert_to_json(rdlc: RDLCompiler, obj: node.RootNode, path: str):# Convert entire register model to primitive datatypes (a dict/list tree)json_obj = convert_addrmap_or_regfile(rdlc, obj.top)# Write to a JSON filewith open(path, "w", encoding='utf-8') as f:json.dump(json_obj, f, indent=4)
5.top_function
import sys# Compile and elaborate files provided from the command line
input_files = sys.argv[1:]
rdlc = RDLCompiler()
try:for input_file in input_files:rdlc.compile_file(input_file)root = rdlc.elaborate()
except RDLCompileError:sys.exit(1)
# Dump the register model to a JSON file
convert_to_json(rdlc, root, "out.json")
input rdl:
addrmap tiny {reg {field {sw=rw;hw=r;} f1[8] = 123;field {sw=r;hw=w;} f2[8];}r1;
};
output json:
{"type": "addrmap","inst_name": "tiny","addr_offset": 0,"children": [{"type": "reg","inst_name": "r1","addr_offset": 0,"children": [{"type": "field","inst_name": "f1","lsb": 0,"msb": 7,"reset": 123,"sw_access": "rw"},{"type": "field","inst_name": "f2","lsb": 8,"msb": 15,"reset": null,"sw_access": "r"}]}]
}