UVM之寄存器模型生成

news2024/12/25 12:29:57

1.采用python脚本生成寄存器模型

首先用excel表格做好寄存器描述

然后编写脚本生成.ralf文件

(1)首先通过openpyxl读取EXCEL表格,

workbook = openpyxl.load_workbook('reg.xlsx')  # 返回一个workbook数据类型的值
 

(2)获得有效表格的整体大小即最大行和列

sheet = workbook['Sheet1']  # 获取某一个表
print(sheet.dimensions)     # 获取表格的尺寸大小
row_num = sheet.max_row     # 行
line_num = sheet.max_column # 列
 

(3)写出寄存器的各部分所对应的列,字母是用于后方访问单元格

reg_column          = 'A'   # 各部分的所在列
address_column      = 'B'
reg_access_column   = 'C'
field_column        = 'D'
field_access_column = 'E'
reset_value_column  = 'F'
bit_end_column      = 'G'
bit_start_column    = 'H'
function_column     = 'I'
 

(4)读取到寄存器名(regname)不为空(None)时先处理寄存器的部分再处理寄存器的域,因为写入.ralf文件的顺序就是先写reg再是field。


(5)按照寄存器名(regname)判断每一个寄存器有几个域(field)。通过regname之间空了多少个来判断。中间穿插了写.ralf的部分。

for i in range(2,row_num+1): #  i < row_num 所以要加一 第一行是描述性的
    j = i
    cell_data = sheet[reg_column + str(i)]
    if(cell_data.value!=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
                reg_filed = end_row - start_row
                print(cell_data.value,"reg  filed is" ,reg_filed )
                break
 

判断逻辑:
当知道regname不为空(None)时,记录当前行数,开始寻找下一个不为空的名字。注意None的第一个字符是大写
在寻找的过程中要保证不能超出最大范围
找到下一个regname不为空的行数,并与之前记录的作差,并记录下field的个数
(6)根据field的个数依次向下x行,读取field的相关信息

 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 = sheet[reset_value_column + str(i+field_num)].value    # 复位值
        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("out for ",i)
 

中间穿插了大量的写文件操作,并且为了.ralf文件内的风格添加了大量空格
最后一行的out for是为了调试时查看是否跳出一次for循环
可以打印以下内容 方便调试。

完整代码如下:

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'   # 各部分的所在列
address_column      = 'B'
reg_access_column   = 'C'
field_column        = 'D'
field_access_column = 'E'
reset_value_column  = 'F'
bit_end_column      = 'G'
bit_start_column    = 'H'
function_column     = 'I'
# 这里只有一个block所在在循环外面写
file_obj.write("block uart_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)]
    if(cell_data.value!=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
                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 = sheet[reset_value_column + str(i+field_num)].value    # 复位值
            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("out for ",i)
file_obj.write("}")
file_obj.close()
print("clear")
SystemExit
 

2.通过ralgen的命令生成寄存器模型

要使用ralgen命令生成寄存器模型,需要以下步骤:

1. 安装ralgen工具。这个工具可以从Accellera官方网站的SystemRDL项目中获取。下载并安装适合你的操作系统的版本。

2. 编写一个SystemRDL描述文件。这个文件描述了寄存器及其字段的属性和行为。

3. 在终端或命令提示符下,使用ralgen命令来生成寄存器模型。命令语法如下:

   ```
   ralgen -l <language> -t <template> -b <base_addr> -o <output_dir> <input_file.rdl>
   ```

   其中,`<language>`是生成模型的目标语言,可以是Verilog、VHDL或SystemVerilog等;`<template>`是使用的模板类型,可以是uvm、sv等;`<base_addr>`是寄存器的基地址;`<output_dir>`是生成模型文件的输出目录;`<input_file.rdl>`是输入的SystemRDL描述文件。

   例如,下面的命令将生成一个UVM的寄存器模型:

   ```
   ralgen -l uvm -t uvm_reg -b 0x1000 -o output my_registers.rdl
   ```

4. 执行ralgen命令后,会生成相应的模型文件。根据你选择的模板类型和目标语言,生成的文件可能包括一个寄存器模型和一个测试模型。

5. 检查生成的模型文件,确保寄存器及其字段的属性和行为与你的SystemRDL描述文件一致。

这样,你就可以通过ralgen命令生成寄存器模型了。请注意根据你的具体需求调整命令参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2257656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

web 期末作业简单设计网页——“我的家乡”网站简单设计

1、网页效果 首页 七彩云南页 旅游攻略页 用户页面 2、源代码 首页 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>首页</title><link rel"stylesheet" href"out.css&quo…

Nanolog起步笔记-10-log解压过程(4)寻找meta续2

Nanolog起步笔记-10-log解压过程4寻找meta续2 写在前面重新开始trace readDictionaryFragment读取meta头部读入每个记录createMicroCode读入头部&#xff0c;和文件名 切分format字符串PrintFragment 后记 写在前面 前面的工作&#xff0c;已做打下令人有信心的基础。 重新开…

编译问题 fatal error: rpc/rpc.h: No such file or directory

在编译一些第三方软件的时候&#xff0c;会经常遇到一些文件识别不到的问题&#xff0c;这里整理下做个归总。 目前可能的原因有&#xff08;排序分先后&#xff09;&#xff1a; 文件不存在&#xff1b;文件存在但路径识别不了&#xff1b;…… 这次以常见的编译lmbench测试…

【OpenCV】Canny边缘检测

理论 Canny 边缘检测是一种流行的边缘检测算法。它是由 John F. Canny 在 1986 年提出。 这是一个多阶段算法&#xff0c;我们将介绍算法的每一个步骤。 降噪 由于边缘检测易受图像中的噪声影响&#xff0c;因此第一步是使用 5x5 高斯滤波器去除图像中的噪声。我们在前面的章…

记录:ubuntu 使用chattts的过程。

你知道什么是穷人吗&#xff1f;穷人就是没钱还想学习。 git GitHub - 2noise/ChatTTS: A generative speech model for daily dialogue. 因为所以。cosyvoice&#xff0c;gpt-s . 0.先找一个目录吧。 1.命令行模式 duyichengduyicheng-computer:~/gitee$ git clone https:…

鸿蒙实现应用通知

目录&#xff1a; 1、应用通知的表现形式2、应用通知消息的实现1、发布普通文本类型通知2、发布进度类型通知3、更新通知4、移除通知 3、设置通知道通展示不同形式通知4、设置通知组5、为通知添加行为意图1、导入模块2、创建WantAgentInfo信息3、创建WantAgent对象4、构造Notif…

Redis篇-6--原理篇5--单线程模型

1、概述 Redis 采用单线程模型来处理客户端请求&#xff0c;这意味着在任意时刻只有一个命令被执行。这种设计简化了 Redis 的实现&#xff0c;并确保了高并发环境下的数据一致性。尽管 Redis 是单线程的&#xff0c;但它通过高效的内存管理和网络 I/O 操作&#xff0c;仍然能…

stm32 GPIO8种输入输出模式

1、分类&#xff1a; 2、输出详解 2.1 推挽输出、复用推挽输出 GPIO_Mode_Out_PP (Output Push-Pull)、GPIO_Mode_AF_PP (Alternate Function Push-Pull) 推挽模式下&#xff0c;内部供电&#xff0c;电路主要控制P-MOS、N-MOS通、断电流实现I/O高、低电平输出 -->应用&…

MongoDB 建模调优change stream实战

MongoDB开发规范 &#xff08;1&#xff09;命名原则。数据库、集合命名需要简单易懂&#xff0c;数据库名使用小写字符&#xff0c;集合名称使用统一命名风格&#xff0c;可以统一大小写或使用驼峰式命名。数据库名和集合名称均不能超过64个字符。 &#xff08;2&#xff09…

【漫话机器学习系列】003.Agglomerative聚类

Agglomerative 聚类&#xff08;层次聚类中的自底向上方法&#xff09; Agglomerative 聚类是一种层次聚类&#xff08;Hierarchical Clustering&#xff09;算法&#xff0c;采用自底向上的策略&#xff0c;将每个数据点看作一个单独的簇&#xff0c;然后逐步将相近的簇合并…

docker的网络类型和使用方式

docker的网络类型 5种网络类型 bridge 默认类型&#xff0c;桥接到宿主机docker0的网络&#xff0c;有点类似于VM虚拟机的NAT网络模型。 案例: docker run --rm -itd --network bridge --name wzy666wzy-bridge alpine host host类型&#xff0c;共享宿主机的网络空间&#…

Java版-图论-最小生成树-Prim算法

实现描述 如图&#xff1a; Prim算法的基本思想是从一个顶点开始&#xff0c;逐步构建最小生成树。具体步骤如下&#xff1a; 随机选取一个顶点作为起始点&#xff0c;并将其加入最小生成树的集合中。从该顶点出发&#xff0c;选择一条边连接到其他未被访问的顶点中的最小权…

ZooKeeper节点扩容

新节点的准备工作&#xff08;这里由hadoop05节点&#xff0c;IP地址为192.168.46.131充当&#xff09; 配置新节点的主机域名映射&#xff0c;并将其通告给集群中的其他节点配置主机间免密登录关闭防火墙并将其加入到开机不启动项同步hadoop01节点的时间将所需要的文件分发给新…

HTML前端开发-- Iconfont 矢量图库使用简介

一、SVG 简介及基础语法 1. SVG 简介 SVG&#xff08;Scalable Vector Graphics&#xff09;是一种基于 XML 的矢量图形格式&#xff0c;用于在网页上显示二维图形。SVG 图形可以无限缩放而不会失真&#xff0c;非常适合用于图标、图表和复杂图形。SVG 文件是文本文件&#x…

厦门凯酷全科技有限公司抖音电商服务的卓越典范

在短视频和直播带货迅速崛起的时代&#xff0c;厦门凯酷全科技有限公司&#xff08;以下简称“凯酷全科技”&#xff09;以其专业的服务、创新的精神以及对市场的深刻理解&#xff0c;在抖音电商领域中脱颖而出&#xff0c;成为众多品牌商家信赖的选择。本文将深入探讨凯酷全科…

电脑运行时提示“0x80240037”错误,提示安装ie插件或其他微软程序时,报错提示“未指定的错误”是什么原因?以及要怎么解决和预防?

电脑运行时0x80240037错误解析&#xff1a;未指定的错误在安装IE插件或微软程序中的原因、解决与预防 作为一名经验丰富的软件开发从业者&#xff0c;我深知电脑在日常使用中可能遇到的各种问题&#xff0c;尤其是安装或更新软件时出现的错误。今天&#xff0c;我们将聚焦于一…

【C++】输入三个整数,输出最大值的高级分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;问题描述&#x1f4af;解题思路&#x1f4af;实现与分析方法一&#xff1a;三元运算符的直接应用详细分析&#xff1a;优缺点剖析&#xff1a; 方法二&#xff1a;显式条件…

类和对象一

目录 1.类的引入 2.类的定义 3.访问限定符 4.类的作用域 5.类对象模型 6.类的大小 1.类的引入 C语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体不仅可以定义变量&#xff0c;也可以定义函数。 C兼容C语言&#xff0c;结构用法可以继续使用 同时sruct也升…

Python爬虫——HTML中Xpath定位

Xpath是一种路径查询语言。利用一个路径表达式从html文档中找到我们需要的数据位置&#xff0c;进而将其写入到本地或者数据库中。 学习Xpath爬虫&#xff0c;我们首先学习一下python中lxml库 关于库 lxml 终端下载Xpath需要用到的模块 pip install lxml 关于HTML 超文本标…

vulnhub靶场【hacksudo】之LPE的后续提权方法学习

前言 靶场&#xff1a;hacksudo-lpe的后几个challenge 基于上篇靶场hacksudo-ple的sudo提权 SUID文件提权 ar文件提权 使用find寻找具有SUID权限的文件 find / -perm -us -type f 2>/dev/null查看ar的SUID用法 sudo install -m xs $(which ar) .TF$(mktemp -u) LFILE&…