【前端验证】通关寄存器与ral_model —— 25种常用寄存器类型全览

news2024/10/7 15:19:14

寄存器的属性分类

本文档对于寄存器的属性以synopsys相关文档以及ral_model生成模型时的识别方式为基准。通常讲可以归纳为以下三个方面:读写属性read-write access、写后值modified write value、读后操作read action。注意,这里指的都是软件的操作,对于硬件侧而言,寄存器无法感知到读行为,对于写行为一般允许通过hw_wen和hw_wdata进行操作。

通过这三方面的属性,可以精准的描述一个寄存器的行为,比如:

在这里插入图片描述
在寄存器的xml描述中,采用如下的方式表示一个field的这三方面属性:

    <spirit:access>read-write</spirit:access>
    <spirit:modifiedWriteValue>oneToSet</spirit:modifiedWriteValue>
    <spirit:readAction>clear</spirit:readAction>

需要注意的是,access是必须要进行描述的,而modifiedWriteValue和readAction则不强制。modifiedWriteValue的缺省属性为总线数据写入,readAction的缺省属性为不改变寄存器值。

因此接下来先看一下这三个方面的属性都有哪些描述符。

Read-write Access

读写属性标记个某个寄存器(在此不区分寄存器reg和域field)是否可以被软件访问。

AccessReadWrite
read-write返回寄存器值参见Modified Write Value
read-only返回寄存器值总线返回error
write-only总线返回error,总线读取值不可预期参见 Modified Write Value
read-writeOnce返回寄存器值复位后只可写一次,写操作参见 Modified Write Value,后续写操作无效
writeOnce总线返回error,总线读取值不可预期复位后只可写一次,写操作参见 Modified Write Value,后续写操作无效

Modified Write Value

写后操作标记了某个寄存器在软件写操后数值的变化。

modifiedWriteValue对应bit写0对应bit写1
NA(缺省)清0置1
oneToClear无影响清0
oneToSet无影响置1
oneToToggle无影响翻转
zeroToClear清0无影响
zeroToSet置1无影响
zeroToToggle翻转无影响
clear清0清0
set置1置1

Read Action

读后行为标记了某个寄存器在软件读操后数值的变化。

readAction
NA(缺省)无影响
clear清0
set置1

寄存器类型与RAL支持情况

结合以上三方面属性以及相关文档和ral_model的实际情况,可以得到下面的25种寄存器行为汇总和ral_model支持情况表格。

属性行为accessmodifiedWriteValuereadActionral是否支持
rw软件可读可写read-writeNANA
ro软件可读,写返回总线报错read-onlyNANA
wo软件可写,读数据报错write-onlyNANA
w1仅复位后可写一次,读数据报错read-writeOnceNANA
w1c写1清0,软件可读read-writeoneToClearNA
rc软件读清零,写报错read-onlyNAclear
rs软件读置1,写报错read-onlyNAset
wrc软件可读写,读清零read-writeNAclear
wrs软件可读写,读置1read-writeNAset
wc软件可读写,写清零read-writeclearNA
ws软件可读写,写置1read-writesetNA
wsrc写置1,读清0read-writesetclear
wcrs写清0,读置1read-writeclearset
w1s写1置1,写0不变,软件可读read-writeoneToSetNA
w1t写1翻转,写0不变,软件可读read-writeoneToToggleNA
w0c写0清0,写1不变,软件可读read-writezeroToClearNA
w0s写0置1,写1不变,软件可读read-writezeroToSetNA
w0t写0翻转,软件可读read-writezeroToToggleNA
w1src写1置1,写0不变,读清0read-writeoneToSetclear
w1crs写1清0,写0不变,读置1read-writeoneToClearset
w0src写0置1,写1不变,读清0read-writezeroToSetclear
w0crs写0清0,写1不变,读置1read-writezeroToClearset
woc写清0,读错误write-onlyclearNA
wos写置1,读错误write-onlysetNA
wo1写置1,仅复位后第一次写有效,读错误writeOnceNANA

关键寄存器类型RTL实现

基于以上所有内容,对关键寄存器进行RTL实现。先确定一下寄存器的接口,个人是倾向于能够把寄存器的接口尽量的统一的,如有特殊情况再进行修改,因此规划的接口如下:

module reg_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);

endmodule

st代表软件操作,hw代表硬件操作。当然了软件操作更常见的信号是sel/en加wen的表示,不过我自己更喜欢wen和ren的方式所以就选了这样的接口规划。

而后需要说明的是,对于软件不可写或软件不可读的寄存器,个人倾向于在寄存器的上层进行控制。若一个寄存器不可写,那么st_wen不应该被上层调度模块拉起,且上层调度模块需要返回一个error状态给到总线。若一个寄存器不可读,那么st_ren同样不应该被拉起,且上层调度模块不应驱动总线上的读数据(使其保持旧值或高阻)同时返回error状态。基于这种思路,那么rw和wo就可以共用代码了,因为软件读的行为由上层处理。

RW/WO

//both for rw/wo
module reg_rw_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(st_wen)
        data_ff <= st_wdata;
    else if(hw_wen)
        data_ff <= hw_wdata;
end

assign rdata = data_ff;

endmodule

RO

只读型寄存器是唯一没有寄存器实体的,直接将内部寄存器的值拉出来即可。

module reg_ro_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input [WD -1:0]hw_wdata,
    output[WD -1:0]rdata
);

assign rdata = hw_wdata;

endmodule

W1

module reg_w1_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;
reg lock_en;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(!lock_en && st_wen)
        data_ff <= st_wdata;
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        lock_en <= 1'b0;
    else if(st_wen)
        lock_en <= 1'b1;
end

assign rdata = data_ff;

endmodule

W1C

module reg_w1c_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= (~st_wdata & data_ff);
end

assign rdata = data_ff;

endmodule

RC

注意,读清寄存器软件读后必须清零,而不是清为复位值。

module reg_rc_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_ren)
        data_ff <= {WD{1'b0}};
end

assign rdata = data_ff;

endmodule

RS

module reg_rs_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_ren)
        data_ff <= {WD{1'b1}};
end

assign rdata = data_ff;

endmodule

WRC

module reg_wrc_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= st_wdata;
    else if(st_ren)
        data_ff <=  {WD{1'b0}};
end

assign rdata = data_ff;

endmodule

WRS

module reg_wrs_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= st_wdata;
    else if(st_ren)
        data_ff <= {WD{1'b1}};
end

assign rdata = data_ff;

endmodule

WC

module reg_wc_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= {WD{1'b0}};
end

assign rdata = data_ff;

endmodule

WS

module reg_wc_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= {WD{1'b1}};
end

assign rdata = data_ff;

endmodule

WSRC

module reg_wsrc_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= {WD{1'b1}};
    else if(st_ren)
        data_ff <= {WD{1'b0}};
end

assign rdata = data_ff;

endmodule

WCRS

module reg_wcrs_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= {WD{1'b0}};
    else if(st_ren)
        data_ff <= {WD{1'b1}};
end

assign rdata = data_ff;

endmodule

W1S

module reg_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= data_ff | st_wdata;
end

assign rdata = data_ff;

endmodule

W1T

软件写1翻转,实际对应的就是原有值与写入值的亦或。

module reg_w1t_field #(
    parameter WD  = 32,
    parameter RST = {WD{1'b0}})
(
    input          clk,
    input          rst_n,

    input          st_wen,
    input          st_ren,
    input [WD -1:0]st_wdata,

    input          hw_wen,
    input [WD -1:0]hw_wdata,

    output[WD -1:0]rdata
);
reg [WD -1:0]data_ff;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        data_ff <= RST;
    else if(hw_wen)
        data_ff <= hw_wdata;
    else if(st_wen)
        data_ff <= st_wdata ^ data_ff;
end

assign rdata = data_ff;

endmodule

其他ral_model不支持的类型我就没有都写完了,仅供参考吧。

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

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

相关文章

chatgpt赋能python:Python怎么升序排序

Python怎么升序排序 排序是我们经常会用到的一种操作&#xff0c;而在Python中&#xff0c;对于列表或数组等序列类型的数据&#xff0c;我们可以使用内置的sorted()函数来进行排序操作。而在排序时&#xff0c;升序排序是我们最常用的一种。 Python中的sorted()函数 sorted…

关于uni-app与vue路由配置的不同,不使用uni.navigateTo接口跳转时,使用this.$router.push的踩坑经验

目录 懵逼的一个小时 uni-app与vue路由配置的不同 非官方接口的另类写法 错误编写&#xff1a; 正确编写&#xff08;只需写父组件即可&#xff0c;其他是多余&#xff09;&#xff1a; 懵逼的一个小时 之前用vue写router路由的时候&#xff0c;先配置一个路由表&am…

chatgpt赋能python:Python怎么删除列表中的最大值和最小值

Python怎么删除列表中的最大值和最小值 在Python中&#xff0c;一个列表&#xff08;List&#xff09;是一种非常常见的数据结构&#xff0c;它允许我们以有序的方式存储和访问数据。但是&#xff0c;有时候我们需要从列表中删除最大或最小的值&#xff0c;以满足我们的特定需…

哈希表原理,以及unordered_set/和unordered_map的封装和迭代器的实现

哈希表 unordered系列unordered_set和unordered_map的使用哈希哈希概念哈希冲突哈希函数闭散列开散列哈希表的扩容哈希表源码&#xff08;开散列和闭散列&#xff09; 封装unordered_set/和unordered_map&#xff0c;以及实现迭代器节点定义unordered_set定义unordered_map定义…

Python3 flask-socketio 整合vue

1. 前端说明 前端追加了vue-socket.io的依赖 更新package.json及package-lock.json后&#xff0c;需要补充库 2. 后端说明 服务端需要安装的python包 suse python 3.6.12 Flask_SocketIO-4.3.1-py2.py3-none-any.whl python_socketio-4.6.0-py2.py3-none-any.whl python_…

在PPT里如何做出晶莹剔透的高级水泡感出来呢

开篇 很多PPT特别是一些TED演讲类PPT,它的首页开篇给人以强烈的冲击感。比如说上面这张PPT,笔者就卖出过一页800元的效果。它的高级高级在以下两个地方: 水晶感;透明感这是时下非常流行的一种TED场景式演讲专用的PPT,适用于一些大厂的CTO、CEO都大量使用这种效果。 今天…

shell脚本编写辅助命令

目录 一、echo 命令 二、字符串相关操作 1.截取字符串 2.获取字符串长度 3.字符串追加字符 4.从开头或结尾删除字符串指定格式内容 三、随机数 1.使用 $RANDOM 2.指定RANDOM变量的范围 &#xff08;1&#xff09;从0开始的范围 &#xff08;2&#xff09;从指定数始…

35、git的使用

一、git简介 git是一款免费、开源的版本控制系统&#xff0c;用于高效地处理任何或大或小的项目。 作用&#xff1a; 文件存档备份 文件版本管理 多人协同合作&#xff08;自动合并&#xff09; 二、git的三个区域 工作区&#xff1a;处理工作的区域 暂存区&#xff1a;临时存放…

Shell脚本实现数组冒泡排序等简单算法排序

目录 一、冒泡排序 1.简介 2.基本思想 3.算法思路 4.shell脚本实现 二、选择排序 1.简介 2.基本思想 3.shell脚本实现 三、插入排序 1.算法思路 2.shell脚本实现 四、反转排序 1.作用 2.shell脚本实现 一、冒泡排序 1.简介 类似气泡上涌的动作&#xff0c;会将…

Java入门之学习随记(三)

一. 栈内存和堆内存 堆内存:存放"引用数据类型的数据"和"new出来的对象",注意-创建出来的对象只包含各自的成员变量,不包括成员方法. 栈内存:存放"基本数据类型的数据","引用数据类型的变量名"以及"对象的引用",但是引用数…

k8s之ReplicaSet回收pod的优先级

ReplicaSet syncReplicaSet的逻辑&#xff0c;首先找到rs下相关的pod // 从informer中获取当前ns下所有的podallPods, err : rsc.podLister.Pods(rs.Namespace).List(labels.Everything())if err ! nil {return err}// 忽略不健康的podfilteredPods : controller.FilterActiveP…

CentOS桥接模式下设置静态IP并解决java.net.ConnectException: Connection timed out: connect

一、前言 最近在配置服务器&#xff0c;DHCP模式下IP地址不固定&#xff0c;每次SSH远程登录连接不上&#xff0c;都要查看新动态分配的IP地址重新配置&#xff0c;感觉些许麻烦&#xff0c;于是给机器配置了静态固定IP。 动态主机配置协议DHCP&#xff08;Dynamic Host Confi…

Shell脚本练习题(附详细解题过程)

目录 一、利用for循环打印99乘法表 二、十进制转二进制 三、将十进制ip地址转换为二进制格式 四、检测某个网段中存活的主机并输出其ip地址 五、检查文件中用户名是否存在并提示创建用户和设置密码 六、检查httpd服务并开启 七、根据百米赛跑成绩判断结果 八、随机数…

栈和队列(数据结构刷题)[一]-python

文章目录 前言一、原理介绍二、用栈实现队列1.操作2.思路 三、关于面试考察栈里面的元素在内存中是连续分布的么&#xff1f; 前言 提到栈和队列&#xff0c;大家可能对它们的了解只停留在表面&#xff0c;再深入一点&#xff0c;好像知道又好像不知道的感觉。本文我将从底层实…

Django----------模板、静态文件、案例(城市天气预报)、请求和响应

目录 1.templates模板 2.静态文件 1.static目录 2.引用静态文件 1.方式一&#xff1a;直接引用 2.方式二&#xff1a;头部及内部引用 3. 模板语法 1.取内容 2.取下标 3.for循环 4.利用字典 5.列表里套字典 6.if条件语句 7.总结 4.案例&#xff08;城市天气预…

CH573-01-GPIO-LED——RISC-V内核BLE MCU快速开发教程

1. 新建工程 1) NEW Project 点击“File->New->MounRiver Project”&#xff1a; 2) finish 选择CH573F的裸机开发工程模板&#xff0c;如下图&#xff0c;然后点击“finish” 3) 编译检查 4) 精简代码 打开工程目录下的./src/main.c文件&#xff0c;修改删掉生成的串口测…

动态规划III (买股票-121、122、123、188)

CP121 买股票的最佳时机 题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利…

Vue 中的几种动画效果

Vue 中的动画效果 在 Vue 中&#xff0c;动画效果是非常常见的交互方式。它可以为用户提供更加生动的交互体验&#xff0c;增强用户的参与感和满意度。在本文中&#xff0c;我们将探讨 Vue 中的动画效果的基本原理和用法&#xff0c;并给出一些实例代码来帮助读者更好地理解。…

『手撕 Mybatis 源码』06 - Mapper 代理方式初始化

Mapper 代理方式初始化 首先修改一下 SqlSession 获取代理对象方式&#xff0c;即通过 getMapper() 来拿到动态代理对象 public class MybatisTest {/*** 问题1&#xff1a;<package name"com.itheima.mapper"/> 是如何进行解析的&#xff1f;* 解答&#xf…

算法刷题-数组-有序数组的平方

977.有序数组的平方 力扣题目链接 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#…