Menu Close

RISC-V Timer Interrupt(1)Access Timer Interrupt  Registers

1. Read the timer interrupt register

 

Related reference articles:

RISC-V teaching plan

 

The exu_lsu module was introduced in the RISC-V LSU, SRAM, GPIO module (1) exu_lsu module before, which allows the RISC-V CPU to access the peripheral module. This article will introduce the submodule fii_timer_lsu under the exu_lsu module that was not mentioned before.

First, refer to the register definition related to timer interrupt on the FII RISC-V Address Map , as shown in Figure 1. It can be seen that there are timer control registers, low 32-bit and high 32-bit registers for timer values, and low 32-bit and high 32-bit registers for timer comparison values. The relevant read (load) code is in the exu_lsu module, see the following code:

Figure 1 Timer Interrupt Register

parameter [ 31: 0 ] TMR_BASEADDR = 32'h0200_0000//Timer interrupt register base address parameter
wire t_sft_cs   = ( i_D_PC[ 31: 16 ] == TMR_BASEADDR[ 31: 16 ] ) ? 1'b1 : 1'b0;//Timer related register chip select
wire sft_cs     = t_sft_cs & ( ( ~i_D_PC[ 12 ] ) & ( i_D_PC[ 5: 2 ] == 0 ) );
wire tm_ctrl_cs = t_sft_cs & ( ( ~i_D_PC[ 12 ] ) & ( i_D_PC[ 5: 2 ] == 1 ) );//timer control register chip select  
wire t_cs0      = t_sft_cs & ( ( ~i_D_PC[ 12 ] ) & ( i_D_PC[ 5: 2 ] == 2 ) );//low 32-bit register chip select of timer value 
wire t_cs1      = t_sft_cs & ( ( ~i_D_PC[ 12 ] ) & ( i_D_PC[ 5: 2 ] == 3 ) );//high 32-bit register chip select of timer value
wire tcmp_cs0   = t_sft_cs & ( ( ~i_D_PC[ 12 ] ) & ( i_D_PC[ 5: 2 ] == 4 ) );//Lower 32-bit register chip select of timer compare value
wire tcmp_cs1   = t_sft_cs & ( ( ~i_D_PC[ 12 ] ) & ( i_D_PC[ 5: 2 ] == 5 ) );//high 32-bit register chip select of timer compare value 

//According to the chip select signal, determine the register to be read 
wire [ 31: 0 ] ls_rb_d_t_sft = sft_cs     ? o_sft_int_v :
                             ( tm_ctrl_cs ? o_tm_ctrl :
                                  ( t_cs0 ? i_timer_l :
                                  ( t_cs1 ? i_timer_h :
                               ( tcmp_cs0 ? o_tcmp_l :
                               ( tcmp_cs1 ? o_tcmp_h : o_CPU_dout ) ) ) ) );

//According to the chip select signal, determine the register to be read  
wire [ 31: 0 ] ls_rb_d = mem_cs ? mem_dout : ( GPIO_cs ? rb_GPIO_d : ( UART_cs ? o_UART_dout : ls_rb_d_t_sft ) );



always@( * )//part of the code block is omitted
begin
if ( i_LOAD )
begin //&mem_init_rdy
    case ( i_load_instr ) // i_load_instr ={rv32i_lbu, rv32i_lb, rv32i_lhu, rv32i_lh, rv32i_lw};
    5'b00001:
    begin //rv32i_lw
        o_wb_data <= ls_rb_d;
    end
    5'b00010:
    begin //rv32i_lh
        o_wb_data <= { { 16{ ls_rb_d[ 15 ] } }, ls_rb_d[ 15: 0 ] };
    end
    5'b00100:
    begin //rv32i_lhu
        o_wb_data <= { { 16{ 1'b0 } }, ls_rb_d[ 15: 0 ] };
    end
    5'b01000:
    begin //rv32i_lb
        o_wb_data <= { { 24{ ls_rb_d[ 7 ] } }, ls_rb_d[ 7: 0 ] };
    end
    5'b10000:
    begin //rv32i_lbu
        o_wb_data <= { { 24{ 1'b0 } }, ls_rb_d[ 7: 0 ] };
    end
default: ;

endcase
end

 

2. Write the timer interrupt register

The write (store) of the timer interrupt register is done in the fii_timer_lsu module. The corresponding register to be written is selected through the write enable signal introduced from the outer module exu_lsu, as well as various chip select signals. code show as below:

wire [31: 0] cpu_data_in = i_rs2_val << {i_D_PC[1:0],3'b000};//The cpu_data_in in the exu_lsu module is finally passed to i_sft_timer_din  

always@( posedge clk or negedge rst_n )
if ( !rst_n )//reset
begin
    o_tm_ctrl <= 0;//initial value
    o_sft_int_v <= 0;
    o_timer_l <= 0;
    o_timer_h <= 0;
    o_tcmp_l <= 0;
    o_tcmp_h <= 16'h8000;
    o_timer_valid <= 0;
end
else
begin
    o_timer_valid <= 0;

    if ( i_tmr_sft_we )//write enable signal
    begin
        if ( i_tcs0 )//The low 32-bit register chip select of the timer value 
        begin
            o_timer_l <= i_sft_timer_din;//Write into the lower 32-bit register of the timer value
            o_timer_valid[ 0 ] <= 1'b1;
        end

        if ( i_tcs1 )//The high 32-bit register chip select of the timer value 
        begin
            o_timer_h <= i_sft_timer_din;//Write into the upper 32-bit register of the timer value
            o_timer_valid[ 1 ] <= 1'b1;
        end

        if ( i_tcmp_cs0 )//The low 32-bit register chip select of the timer comparison value 
            o_tcmp_l <= i_sft_timer_din;//Write into the lower 32-bit register of the timer comparison value

        if ( i_tcmp_cs1 )//The high 32-bit register chip select of the timer comparison value 
            o_tcmp_h <= i_sft_timer_din;//Write into the upper 32-bit register of the timer comparison value

        if ( i_tm_ctrl_cs )//Timer control register chip select 
            o_tm_ctrl <= i_sft_timer_din;//Write into the timer control register
    end
end

 

 

Posted in FPGA, RISC-V, RISC-V Textbook, Textbook and Training Project

Related Articles

Leave a Reply

Your email address will not be published.

Leave the field below empty!