tinyriscv_timer

本文详细介绍了一个嵌入式系统中使用定时器进行计数和中断控制的设计,涉及输入输出、内部寄存器操作、计数器功能、读写寄存器的逻辑以及中断信号处理。通过实例展示了如何配置定时器、控制计数和触发中断,适合深入理解嵌入式硬件编程。
摘要由CSDN通过智能技术生成

目录

输入输出

内部寄存器

中断输出

写寄存器

计数器

读寄存器(组合逻辑)

仿真


输入输出

    input wire              clk,
    input wire              rst,

    input wire  [31:0]      data_i,
    input wire  [31:0]      addr_i,
    input wire              we_i,       

    output reg  [31:0]      data_o,     //输出
    output wire             int_sig_o    //中断信号

内部寄存器

    localparam REG_CTRL = 4'h0;         //addr_i[3:0]对应的控制  控制字段 
    localparam REG_COUNT = 4'h4;        //计数  控制字段
    localparam REG_VALUE = 4'h8;        //计数最大  控制字段

    // [0]: timer enable
    // [1]: timer int enable
    // [2]: timer int pending, write 1 to clear it(中断发生等待响应)
    // addr offset: 0x00
    reg[31:0] timer_ctrl;

    // timer current count, read only
    // addr offset: 0x04
    reg[31:0] timer_count;

    // timer expired value
    // addr offset: 0x08
    reg[31:0] timer_value;

中断输出

 //中断信号在中断发生等待响应和中断使能的情况下拉高
 assign int_sig_o = ((timer_ctrl[2] == 1'b1) && (timer_ctrl[1] == 1'b1))? 1'b1: 1'b0;

写寄存器

//写寄存器
always @(posedge clk ) begin
    if(rst==1'b0)begin
        timer_ctrl<=32'b0;
        timer_value<=32'b0;

    end else begin
        if(we_i==1'b1)begin
            case (addr_i[3:0])
                REG_CTRL: begin
                    //计时器使能克计时器中断使能直接赋值    data_i[2]=1即已经响应拉低timer_ctrl[2]
                    timer_ctrl<= {timer_ctrl[31:3],(timer_ctrl[2] & (~data_i[2])),data_i[1:0]};                                                                                                                        
                end
                REG_VALUE: begin
                    timer_value<=data_i;
                end
                 
            endcase
        end else begin//如果计数达到最大置并且定时器使能(只有使能才会计数)
            if((timer_count==timer_value)&&(timer_ctrl[0]==1'b1))begin
                timer_ctrl[0]=1'b0;
                timer_ctrl[2]=1'b1;

            end

        end

    end
   
end

计数器

//计数器
always @(posedge clk) begin
    if (rst==1'b0) begin
        timer_count<=32'b0;
    end else begin
        if(timer_ctrl[0]==1'b1)begin
            timer_count<=timer_count+1'b1;
            if(timer_count==timer_value)begin
                timer_count<=32'b0;
            end
        end else begin

            timer_count<=32'b0;

        end
    end
    
end

读寄存器(组合逻辑)

//计数器
always @(posedge clk) begin
    if (rst==1'b0) begin
        timer_count<=32'b0;
    end else begin
        if(timer_ctrl[0]==1'b1)begin
            timer_count<=timer_count+1'b1;
            if(timer_count==timer_value)begin
                timer_count<=32'b0;
            end
        end else begin

            timer_count<=32'b0;

        end
    end
    
end

仿真

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/07/20 09:46:43
// Design Name: 
// Module Name: timersim
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module timersim(

    );
    reg              clk;
    reg              rst;

    reg  [31:0]      data_i;
    reg  [31:0]      addr_i;
    reg              we_i;       

    wire [31:0]      data_o;     //输出
    wire             int_sig_o;    //中断信号wire    

    localparam REG_CTRL = 4'h0;         //addr_i[3:0]对应的控制  控制字段 
    localparam REG_COUNT = 4'h4;        //计数  控制字段
    localparam REG_VALUE = 4'h8;        //计数最大  控制字段


    timer timer_init(
    .clk(clk),
    .rst(rst),
    .data_i(data_i),
    .addr_i(addr_i),
    .we_i(we_i),       
    .data_o(data_o),     //输出
    .int_sig_o(int_sig_o)   //中断信号
    );

    initial begin
        clk=1'b1;
        rst=1'b0;
        we_i=1'b0;
        #20
        rst=1'b1;
        #20
        we_i=1'b1;
        addr_i={28'b0,REG_VALUE};
        data_i=32'd15;
        #20
        addr_i={28'b0,REG_CTRL};
        data_i={30'b0,2'b11};
        #60
        we_i<=1'b0;
        addr_i={28'b0,REG_CTRL};//读REG_CTRL
        #20
        addr_i={28'b0,REG_VALUE};//读REG_VALUE
    end
    always begin
        #10
        clk=~clk;
    end

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值