生成ralf文件

本文参考使用Python脚本生成.ralf文件生成寄存器模型-CSDN博客

在其基础上,做了一些改进,假如有上百个相似的寄存器时可以使用,比如pinmux有上百个GPIO口,每个gpio口都有类似的寄存器域,这样使用excel再进行生成就显得有些麻烦

比如

CHR_CSR寄存器,共有128个,因此定义了起始地址0x100,结束地址0x8f0,还有每次地址递增量16.

使用的python脚本如下:

import os
import openpyxl
dst_filename = 'mgc_uart_reg.ralf'
workbook = openpyxl.load_workbook('reg.xlsx')  # 返回一个workbook数据类型的值
file_obj = open(dst_filename,'w') # 打开目标文件
print(workbook.sheetnames)  # 打印Excel表中的所有表
sheet = workbook['Sheet1']  # 获取某一个表
print(sheet.dimensions)     # 获取表格的尺寸大小
row_num = sheet.max_row     # 行
line_num = sheet.max_column # 列

reg_column          = 'A'   # 各部分的所在列
start_address_column= 'B'
end_address_column  = 'C'
reg_access_column   = 'D'
field_column        = 'E'
field_access_column = 'F'
reset_value_column  = 'G'
bit_end_column      = 'H'
bit_start_column    = 'I'
incriment_column    = 'J'
function_column     = 'K'
# 这里只有一个block所在在循环外面写
file_obj.write("block pdma_reg_block { \n")
file_obj.write("    bytes " + str(11)+';\n') # byte 
for i in range(2,row_num+1): #  i < row_num 所以要加一 第一行是描述性的
    j = i
    cell_data = sheet[reg_column + str(i)]
    start_cell_address=f"{start_address_column}{i}"
    end_cell_address=f"{end_address_column}{i}"
    incr_cell_address=f"{incriment_address_column}{i}"
    start_address=sheet[start_cell_address].value
    end_address=sheet[end_cell_address].value
    incr=sheet[incr_cell_address].value
    if((cell_data.value!=None) and (end_address==None)): # 处理寄存器域
        start_row = cell_data.row
        # 寄存器的相关属性
        reg_name = cell_data.value
        reg_addr = sheet[address_column + str(i)].value
        reg_access = sheet[reg_access_column + str(i)].value
        file_obj.write("    register " + reg_name+ " @" +reg_addr+" {\n")
        # file_obj.write("bytes " + str(1)) # byte 没有则自动计算
        print("reg name is",reg_name,"reg addr is ",reg_addr,"reg access is ",reg_access)
        while(1):
            j += 1
            if(j < row_num):
                if(sheet[reg_column + str(j)].value!=None):
                    end_row = j 
                    reg_filed = end_row - start_row 
                    print(cell_data.value,"reg  filed is" ,reg_filed )
                    break
            else:
                end_row = j+1
                reg_filed = end_row - start_row
                print(cell_data.value,"reg  filed is" ,reg_filed )
                break

        for field_num in range(0,reg_filed) :
            fiedl_name = sheet[field_column+str(i+field_num)].value                 # 域的名字
            print("fiedl_name is ",fiedl_name)
            field_access = sheet[field_access_column+str(i+field_num)].value        # 域的access
            print("field access is ",field_access)
            field_reset_num_str = sheet[reset_value_column + str(i+field_num)].value
            field_reset_num = str(field_reset_num_str)[2:]    # 复位值
            print("field_reset_nume ",field_reset_num)
            field_bit_start = sheet[bit_start_column+str(i+field_num)].value        # 起始位数
            field_bit_end = sheet[bit_end_column+str(i+field_num)].value            # 最终位数
            field_bits = field_bit_end - field_bit_start + 1                        # 共计多少bit
            print("bit start " , field_bit_start , "end " ,field_bit_end ,"bits " ,field_bits)
            file_obj.write("        field " + str(fiedl_name)+" {\n")
            file_obj.write("            bits " + str(field_bits)+";\n")
            file_obj.write("            reset " + str(field_reset_num)+";\n")
            file_obj.write("            access " + str(field_access).lower()+";\n") # ralgen 区分大小写
            file_obj.write("        }\n")
        file_obj.write("    }\n")   
    print("addr loop ",i)
    if((cell_data.value!=None) and (end_address!=None)): # 处理寄存器域
        start_address=int(start_address,16)
        end_address=int(end_address,16)
        incr=int(incr)
        for s in range(start_address,end_address,incr) :
            j = i
            start_row = cell_data.row
            # 寄存器的相关属性
            reg_name = cell_data.value
            reg_addr = hex(s)
            reg_addr = str(reg_addr)
            num=int((s - start_address)/incr)
            num=str(num)
            reg_access = sheet[reg_access_column + str(i)].value
            file_obj.write("    register " + reg_name+num+ " @" +reg_addr+" {\n")
            # file_obj.write("bytes " + str(1)) # byte 没有则自动计算
            print("reg name is",reg_name,"reg addr is ",reg_addr,"reg access is ",reg_access)
            while(1):
                j += 1
                if(j < row_num):
                    if(sheet[reg_column + str(j)].value!=None):
                        end_row = j 
                        reg_filed = end_row - start_row 
                        print(cell_data.value,"reg  filed is" ,reg_filed )
                        break
                else:
                    end_row = j+1
                    reg_filed = end_row - start_row
                    print(cell_data.value,"reg  filed is" ,reg_filed )
                    break

            for field_num in range(0,reg_filed) :
                fiedl_name = sheet[field_column+str(i+field_num)].value                 # 域的名字
                print("fiedl_name is ",fiedl_name)
                field_access = sheet[field_access_column+str(i+field_num)].value        # 域的access
                print("field access is ",field_access)
                field_reset_num_str = sheet[reset_value_column + str(i+field_num)].value
                field_reset_num = str(field_reset_num_str)[2:]    # 复位值
                print("field_reset_nume ",field_reset_num)
                field_bit_start = sheet[bit_start_column+str(i+field_num)].value        # 起始位数
                field_bit_end = sheet[bit_end_column+str(i+field_num)].value            # 最终位数
                field_bits = field_bit_end - field_bit_start + 1                        # 共计多少bit
                print("bit start " , field_bit_start , "end " ,field_bit_end ,"bits " ,field_bits)
                file_obj.write("        field " + str(fiedl_name)+" {\n")
                file_obj.write("            bits " + str(field_bits)+";\n")
                file_obj.write("            reset " + str(field_reset_num)+";\n")
                file_obj.write("            access " + str(field_access).lower()+";\n") # ralgen 区分大小写
                file_obj.write("        }\n")
            file_obj.write("    }\n")   
        print("addr loop ",i)
    print("out for ",i)
file_obj.write("}")
file_obj.close()
print("clear")
SystemExit

使用的makefile如下:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的Python脚本示例,用于从CSV文件生成RAL描述文件,并调用vcs的ralgen命令生成UVM寄存器模型: ```python import csv import os import subprocess # 读取CSV文件 def read_csv_file(csv_file): with open(csv_file, 'r') as f: reader = csv.DictReader(f) return [row for row in reader] # 生成RAL描述文件 def generate_ralf_file(ralf_file, registers): with open(ralf_file, 'w') as f: for reg in registers: f.write("reg %s {\n" % reg['name']) f.write(" address 0x%s;\n" % reg['address']) f.write(" description \"%s\";\n" % reg['description']) f.write(" permission %s;\n" % reg['permission']) f.write(" field %s {\n" % reg['field_name']) f.write(" description \"%s\";\n" % reg['field_description']) f.write(" access %s;\n" % reg['field_access']) f.write(" bit %d..%d;\n" % (reg['field_from'], reg['field_to'])) f.write(" }\n") f.write("}\n\n") # 调用vcs的ralgen命令生成UVM寄存器模型 def generate_uvm_model(ralf_file, uvm_file): cmd = "ralgen -t uvm -l sv -c -f %s %s" % (uvm_file, ralf_file) subprocess.call(cmd, shell=True) # 主函数 if __name__ == '__main__': csv_file = 'registers.csv' ralf_file = 'registers.ralf' uvm_file = 'registers_uvm.sv' # 读取CSV文件 registers = read_csv_file(csv_file) # 生成RAL描述文件 generate_ralf_file(ralf_file, registers) # 调用vcs的ralgen命令生成UVM寄存器模型 generate_uvm_model(ralf_file, uvm_file) # 删除临时生成的RAL描述文件 os.remove(ralf_file) ``` 这个脚本假设你的CSV文件中的每一行都包含以下字段: - name:寄存器名称 - address:寄存器地址 - description:寄存器描述 - permission:寄存器访问权限 - field_name:寄存器字段名称 - field_description:寄存器字段描述 - field_access:寄存器字段访问权限 - field_from:寄存器字段起始位 - field_to:寄存器字段结束位 你需要将脚本中的文件名和路径更改为你自己的文件名和路径。同时,你需要确保你的系统上安装了vcs,并且可以在命令行中调用ralgen命令。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值