今天来看一个具体实例,上一篇传送门: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_name
json_obj['lsb'] = obj.lsb
json_obj['msb'] = obj.msb
json_obj['reset'] = obj.get_property('reset')
json_obj['sw_access'] = obj.get_property('sw').name
return 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 RDLCompileError
rdlc.msg.fatal(
"JSON export does not support arrays",
obj.inst.inst_src_ref
)
# Convert information about the register
json_obj = dict()
json_obj['type'] = 'reg'
json_obj['inst_name'] = obj.inst_name
json_obj['addr_offset'] = obj.address_offset
# Iterate over all the fields in this reg and convert them
json_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 RuntimeError
json_obj['inst_name'] = obj.inst_name
json_obj['addr_offset'] = obj.address_offset
json_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 file
with 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"
}
]
}
]
}