首页 > 其他 > 详细

OR1200处理器的计时器模块TT介绍

时间:2014-07-02 16:33:51      阅读:525      评论:0      收藏:0      [点我收藏+]

以下内容摘自《步步惊芯——软核处理器内部设计分析》一书

 

16.2.1 TT介绍

      计时器模块(Tick TimerTT)一般用在操作系统的进程调度、用户程序的定时参考等。TT内部会对时钟周期计数,当计数值达到一个预设值时,会产生中断,通知处理器进行处理。其实现的主体是两个特殊寄存器:计时器单元计数寄存器TTCR、计时器单元模式寄存器TTMR,通过这两个SPR的不同配置,实现不同的工作模式,以及计时中断的产生。TTCRTTMR是第10组特殊寄存器,如表16.4所示。TTCRTTMR的格式分别如表16.516.6所示。

bubuko.com,布布扣

      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开始的接口都是与特殊寄存器读写有关的信号,含义也很明了,此外,intr1表示计时器中断发生,该信号输出到CPU模块的接口sig_tick

bubuko.com,布布扣

      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介绍,布布扣,bubuko.com

OR1200处理器的计时器模块TT介绍

原文:http://blog.csdn.net/leishangwen/article/details/36411165

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!