OR1200处理器的计时器模块TT介绍
以下内容摘自《步步惊芯——软核处理器内部设计分析》一书
16.2.1 TT介绍
计时器模块(Tick Timer:TT)一般用在操作系统的进程调度、用户程序的定时参考等。TT内部会对时钟周期计数,当计数值达到一个预设值时,会产生中断,通知处理器进行处理。其实现的主体是两个特殊寄存器:计时器单元计数寄存器TTCR、计时器单元模式寄存器TTMR,通过这两个SPR的不同配置,实现不同的工作模式,以及计时中断的产生。TTCR、TTMR是第10组特殊寄存器,如表16.4所示。TTCR、TTMR的格式分别如表16.5、16.6所示。
TTMR中各个标志位的含义如下:
- TP:预设的计时器周期,范围是0x0-0xFFFFFFF
- IP:为1表示有计时器中断等待处理
- IE:为1表示允许计时器产生中断,反之计时器不会产生中断
- M:计时器的工作模式
其中TTMR[M]的值决定了计时器的工作模式,共有4种工作模式,每种模式下计时器的工作过程如下:
(1)自动重新开始模式Auto-restart Mode
TTMR[M]等于2’b01时,TT工作于自动重新开始模式,在这种模式下,当TTCR[27:0]的值等于TTMR[TP]的值时,会将TTCR清零,然后继续计时,如果TTMR[IE]为1,那么还会声明计时器中断。
(2)一次计时模式One-shot Mode
TTMR[M]等于2’b10时,TT工作于一次计时模式,在这种模式下,当TTCR[27:0]的值等于TTMR[TP]的值时,会停止计时,如果TTMR[IE]为1,那么还会声明计时器中断。改写TTCR后,可以继续计时。
(3)连续计时模式Continuous Mode
TTMR[M]等于2’b11时,TT工作于连续计时模式,在这种模式下,当TTCR[27:0]的值等于TTMR[TP]的值时,会继续计时,也就是TTCR的值继续累加,如果TTMR[IE]为1,那么还会声明计时器中断。
(4)计时器停止模式Stop Mode
TTMR[M]等于2’b00时,TT停止工作。
上述各种模式下,声明计时器中断实际就是设置TTMR[IP]的值为1,处理器响应计时器中断后会进入计时器中断处理例程,但是TTMR[IP]不会自动清零,需要通程序过向TTMR[IP]写入0的方式清零。
16.2.2 TT的对外连接关系及相关宏定义
OR1200中计时器模块TT的对外连接关系如图16.2所示,通过箭头方向表示该信号是输入还是输出。以spr_xxx开始的接口都是与特殊寄存器读写有关的信号,含义也很明了,此外,intr为1表示计时器中断发生,该信号输出到CPU模块的接口sig_tick。
OR1200中与计时器有关的宏定义如下:
or1200_defines.v
`define OR1200_TT_IMPLEMENTED //是否实施TT模块,TT模块是可选模块
`define OR1200_TT_OFS_TTMR 1'd0 //TTMR、TTCR寄存器在第10组特殊寄存器中的索引
`define OR1200_TT_OFS_TTCR 1'd1
`define OR1200_TTOFS_BITS 0
`define OR1200_TT_TTMR //需要定义这个宏才能使用TTMR寄存器
`define OR1200_TT_TTCR //需要定义这个宏才能使用TTCR寄存器
`define OR1200_TT_TTMR_TP 27:0 //TTMR中各个标识位的偏移
`define OR1200_TT_TTMR_IP 28
`define OR1200_TT_TTMR_IE 29
`define OR1200_TT_TTMR_M 31:30
`define OR1200_TT_READREGS //有了这个宏定义标识,才可以读TT中的特殊寄存器TTMR、TTCR
16.2.3 TT代码分析
TT的代码主要就是配置计时器不同的工作模式,并在各种工作模式下改变TTCR、控制计时器中断的产生。代码分析如下(为了便于理解,笔者改变了代码顺序):
or1200_tt.v
module or1200_tt(
// RISC Internal Interface
clk, rst, du_stall, spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o, intr
);
……
`ifdef OR1200_TT_IMPLEMENTED
`ifdef OR1200_TT_TTMR
reg [31:0] ttmr; //TTMR寄存器
`else
wire [31:0] ttmr;
`endif
`ifdef OR1200_TT_TTCR
reg [31:0] ttcr; // TTCR寄存器
`else
wire [31:0] ttcr;
`endif
……
//如果spr_cs为1,那么依据spr_addr的最低位判断指令l.mfspr/l.mtspr的访问目标是
//TTMR还是TTCR,ttmr_sel为1,表示访问目标是TTMR;ttcr_sel为1,表示访问目标是TTCR
assign ttmr_sel = (spr_cs && (spr_addr[`OR1200_TTOFS_BITS] == `OR1200_TT_OFS_TTMR)) ?
1'b1 : 1'b0;
assign ttcr_sel = (spr_cs && (spr_addr[`OR1200_TTOFS_BITS] == `OR1200_TT_OFS_TTCR)) ?
1'b1 : 1'b0;
//当TTMR[TP]等于TTCR[27:0]时,match等于1
assign match = (ttmr[`OR1200_TT_TTMR_TP] == ttcr[27:0]) ? 1'b1 : 1'b0;
//当工作在Auto-retart模式,且TTMR[TP]等于TTCR[27:0]时,会设置restart为1
assign restart = match && (ttmr[`OR1200_TT_TTMR_M] == 2'b01);
//stop为1的情况有三种:(1)当工作在One-shot模式,且TTMR[TP]等于TTCR[27:0]时,
//会停止计时,设置stop为1;(2)当TTMR[M]为2’b00时,计时器不工作,stop为1;
//(3)外部中断单元设置定时器停止,此时du_stall为1
assign stop = match &
(ttmr[`OR1200_TT_TTMR_M] == 2'b10) | (ttmr[`OR1200_TT_TTMR_M] == 2'b00) | du_stall;
`ifdef OR1200_TT_TTMR
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
ttmr <= 32'b0;
else if (ttmr_sel && spr_write)
ttmr <= spr_dat_i; //如果ttmr_sel为1,且spr_write为1,表示写TTMR
else if (ttmr[`OR1200_TT_TTMR_IE]) // TTMR[IE]为1表示中断使能,那么当match等于1时,
//会设置TTMR[IP]为1,并且TTMR[IP]的值不会自动清零
ttmr[`OR1200_TT_TTMR_IP] <= ttmr[`OR1200_TT_TTMR_IP] | (match & ttmr[`OR1200_TT_TTMR_IE]);
`else
assign ttmr = {2'b11, 30'b0}; //没有设置TTMR寄存器的情况下,变量ttmr的值
`endif
//从图16.2可知intr连接至CPU的输入sig_tick接口,intr的值就是TTMR[IP]的值,表示计时器中断是否发生
assign intr = ttmr[`OR1200_TT_TTMR_IP];
`ifdef OR1200_TT_TTCR
always @(posedge clk or `OR1200_RST_EVENT rst)
if (rst == `OR1200_RST_VALUE)
ttcr <= 32'b0;
else if (restart) //当工作在Auto-restart模式,且TTMR[TP]等于TTCR[27:0]
//时会设置restart为1,此时将TTCR清零,重新开始计数
ttcr <= 32'b0;
else if (ttcr_sel && spr_write) //ttcr_sel为1,且spr_write为1,表示写TTCR寄存器
ttcr <= spr_dat_i;
else if (!stop) //只要stop不为1,那么每个时钟周期TTCR的值加1
ttcr <= ttcr + 32'd1;
`else
assign ttcr = 32'b0; //没有设置TTCR寄存器的情况下,变量ttcr的值
`endif
always @(spr_addr or ttmr or ttcr)
case (spr_addr[`OR1200_TTOFS_BITS]) // synopsys parallel_case
`OR1200_TT_OFS_TTMR: spr_dat_o = ttmr; //读TTMR
default: spr_dat_o = ttcr; //读TTCR
endcase
`else //在没有配置TT模块的情况下intr始终为0,没有计时器中断
assign intr = 1'b0;
assign spr_dat_o = 32'b0;
`endif
endmodule
OR1200处理器的计时器模块TT介绍相关推荐
- or1200处理器的异常处理类指令介绍
下面内容摘自<步步惊芯--软核处理器内部设计分析>一书 我们在计算机体系结构的学习中知道:中断实质上包含由外部事件引起的硬中断(又称外中断)和由内部预先安排的特定指令或内部异常引起的软中断 ...
- or1200处理器的SPRS模块详细分析
以下内容摘自<步步惊芯--软核处理器内部设计分析>一书 前面两节以访问映射到SPR地址空间的通用寄存器为例分别介绍了l.mfspr.l.mtspr指令的一般过程,访问其余特殊寄存器的取指. ...
- OR1200处理器中Wishbone总线接口模块WB_BIU介绍
下面内容摘自<步步惊芯--软核处理器内部设计分析>一书 WB_BIU模块是OR1200处理器与外部Wishbone总线连接的接口模块.15.1节给出了WB_BIU模块的对外连接关系,并指出 ...
- ESP8266 中断(Interrupts)和计时器(Timers)功能介绍
ESP8266 中断(Interrupts)和计时器(Timers)功能介绍 在本指南中,您将学习如何使用Arduino IDE与ESP8266 NodeMCU使用中断和计时器.中断允许您检测GPIO ...
- 正则表达式re模块使用介绍
1. re模块的介绍 在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个 re 模块 # 导入re模块 import re# 使用match方法进行匹配操作 result = re ...
- oracle订单,银科软件:Oracle ERP订单管理模块详细介绍
原标题:银科软件:Oracle ERP订单管理模块详细介绍 Oracle® 订单管理使用户能够通过更有效的客户服务.更个性化的产品和更有利的价格制定和订单履行抢先利用日益发展的国际互联网去销售和让客户 ...
- python图像处理模块_Python图像处理库PIL的ImageEnhance模块使用介绍
Python图像处理库PIL的ImageEnhance模块使用介绍 发布时间:2020-08-31 20:08:55 来源:脚本之家 阅读:66 ImageEnhance模块提供了一些用于图像增强的类 ...
- IDEA下Maven多模块项目介绍和搭建
为什么80%的码农都做不了架构师?>>> 1Maven多模块项目介绍 为了便于演示和表达,在intellij中建了小项目进行举例,如下图所示 其中web-m2模块,依赖于com ...
- ISP各个模块功能介绍
ISP各个模块功能介绍
最新文章
- 网站前端和后台性能优化18
- 关于IE控件闪烁解决方案
- Charles抓包https
- 关于 eclipse 插件JsonEditorPlugin-0.9.4安装与使用
- 对于我今后人生受益匪浅的几句话
- 交大计算机学硕往年录取情况,上海交通大学2020年考研报录情况汇总及分析
- linux内核之kfifo队列
- beetl调用java方法_08.自定义方法以及直接访问java类方法---《Beetl视频课程》
- 示例1---从记事本中读取数值,然后写到数组中---切片,优化版本
- 中秋前小假期的一些想法
- 史上最强图标下载,3124个图标专辑,超过60万免费图标提供下载
- 某宝长x-mini-wua分析与破解
- 安装 Tableau Desktop 时出现“0x80070109”错误以及Tableau Desktop破解
- [V811双核] 最新昂达V811最新2.0固件ROOT方法
- OKHttp原理讲解之责任链模式及扩展
- 内网visual studio code remote-ssh远程离线服务器
- 039.并发编程之线程
- Mysql Workbench connection ssl not enable问题解决
- 修复 Rancher 2.5.x 内部证书过期导致无法启动的顽疾
- 低学历转行3D建模有前途吗,游戏3D建模怎么样?