Menu Close

RISC-V CSR读写控制(5)CSR寄存器实现下

相关参考文章:

RISC-V教学教案

 

本文将完成最后剩下的CSR寄存器实现,之前已经介绍的CSR寄存器实现参考下面两篇文章:

RISC-V CSR读写控制(3)CSR寄存器实现上

RISC-V CSR读写控制(4)CSR寄存器实现中

 

 

1.8. csr_misa

misa寄存器可读可写,存储RISC-V CPU的信息,比如架构和支持的基本/压缩指令集。实现misa寄存器的部分重要代码如下(与上文重复的代码省略):

output [31:0] o_misa//输出misa寄存器


assign o_misa = {
2'b1 // 最高两位为2b'01表示为32位架构
,4'b0 // WIRI
,1'b0 // 25 Z Reserved
,1'b0 // 24 Y Reserved
,1'b0 // 23 X Non-standard extensions present
,1'b0 // 22 W Reserved
,1'b0 // 21 V Tentatively reserved for Vector extension 20 U User mode implemented
,1'b0 // 20 U User mode implemented
,1'b0 // 19 T Tentatively reserved for Transactional Memory extension
,1'b0 // 18 S Supervisor mode implemented
,1'b0 // 17 R Reserved
,1'b0 // 16 Q Quad-precision floating-point extension
,1'b0 // 15 P Tentatively reserved for Packed-SIMD extension
,1'b0 // 14 O Reserved
,1'b0 // 13 N User-level interrupts supported
,1'b0 // 12 M Integer Multiply/Divide extension
,1'b0 // 11 L Tentatively reserved for Decimal Floating-Point extension
,1'b0 // 10 K Reserved
,1'b0 // 9 J Reserved
,1'b1 // <= 8 I RV32I/64I/128I base ISA//目前实现的基本指令集是RV32I,32位整型的指令集
,1'b0 // 7 H Hypervisor mode implemented
,1'b0 // 6 G Additional standard extensions present
,1'b0 // 5 F Single-precision floating-point extension
,1'b0 // 4 E RV32E base ISA 
,1'b0 // 3 D Double-precision floating-point extension
,1'b0 // 2 C Compressed extension
,1'b0 // 1 B Tentatively reserved for Bit operations extension
,1'b0 // 0 A Atomic extension
};

 

1.9. csr_mcounteren

mcounteren寄存器是可读可写的,每一位分别对应一组计数器,无论CSR指令写入什么值,相应的计数器不受影响。mcounteren控制的是下一个特权级别是否能读出相应的计数器,如果相应的位为0,则尝试读出计数器会引起非法指令异常。如下图所示。

%title插图%num

因为这里只实现了机器模式,所以没有用mcounteren。这里只实现了mcounteren的读写。实现mcounteren寄存器的部分重要代码如下(与上文重复的代码省略):

output [ 31: 0 ] o_mcounteren,//输出mcounteren


wire mcounteren_ena = (i_csr_wen & (i_csr_addr == 12'h306));//通过地址索引确认寄存器
wire [31:0] mcounteren_r;
wire [31:0] mcounteren_nxt = i_csr_val;

fii_dfflr #(32) mtvec_dfflr (mcounteren_ena, mcounteren_nxt, mcounteren_r, sys_clk, rst_n);//锁存

assign o_mcounteren = mcounteren_r;//输出


 

1.10. csr_mid

csr_mid模块中组合了很多和ID相关的寄存器,有mvendorid,marchid,mimpid和mhartid。这四个寄存器都是只读的。寄存器的具体含义参考RISC-V CSR寄存器(2)CSR寄存器中的1.7-1.10。寄存器实现的部分重要代码如下(与上文重复的代码省略):

output [31:0] o_mvendorid, //输出mvendorid
output [31:0] o_marchid,   //输出marchid
output [31:0] o_mimpid,    //输出mimpid
output [31:0] o_mhartid    //输出mhartid

//以下的三个ID没有完全实现
assign o_mvendorid = 32'b0;
assign o_marchid   = 32'b0;
assign o_mimpid    = 32'b0;
assign o_mhartid   = 32'b0;//hart ID为0表示CPU是单核


1.11. csr_scratch

mscratch寄存器是机器模式下可读可写,没有指定的用法。实现mscratch寄存器的部分重要代码如下(与上文重复的代码省略):

output [ 31: 0 ] o_mscratch, //输出mscratch

wire mscratch_ena = (i_csr_wen & (i_csr_addr == 12'h340)); //通过地址索引确认寄存器
wire [31:0] mscratch_r;
wire [31:0] mscratch_nxt = i_csr_val;

fii_dfflr #(32) mtvec_dfflr (mscratch_ena, mscratch_nxt, mscratch_r, sys_clk, rst_n);//锁存

assign o_mscratch = mscratch_r;//输出



1.12. csr_mcycle

csr_mcylce模块包括mcycle和mcycleh两个寄存器,用于计数过了多少个时钟周期。两个32位计数器组成一个64位的计数器。实现计数器的部分重要代码如下(与上文重复的代码省略):

 

//调试相关信号
input i_dbg_mode,
input i_dbg_stpcyl,


output reg [ 31: 0 ] o_mcycle_l,//输出mcycle寄存器,低32位
output reg [ 31: 0 ] o_mcycle_h,//输出mcycleh寄存器,高32位


wire dbg_stop = i_dbg_mode & i_dbg_stpcyl;//调试开始

always@( posedge sys_clk or negedge rst_n )
if ( !rst_n )//如果没有复位
begin
    o_mcycle_l <= 32'b0;
    o_mcycle_h <= 32'b0;
end
else if ( i_csr_wen )//CSR寄存器可写
begin
    case ( i_csr_addr )//CSR指令写入,根据地址索引到低位/高位寄存器
    12'hb00: o_mcycle_l <= i_csr_val;
    12'hb80: o_mcycle_h <= i_csr_val;
    default: ;
    endcase
end
else
begin
    if ( !dbg_stop )//如果不处于调试
    begin
        if ( o_mcycle_l == 32'hffff_ffff )//如果低32位寄存器已满
        begin
            o_mcycle_h <= o_mcycle_h + 1;//高位进位
            o_mcycle_l <= 0;
        end
        else
            o_mcycle_l <= o_mcycle_l + 1;//低32位的寄存器加1
    end
end



1.13. csr_minstret

 

csr_minstret模块与上面的csr_mcycle模块类似,包括minstret和minstreth两个32位寄存器,用来组成一个64位寄存器。minstret和minstreth主要用来计数已经执行过的指令。实现寄存器的部分重要代码如下(与上文重复的代码省略):

 

input i_EXE_vld,//判断是否处在执行阶段

//调试相关信号
input i_dbg_mode,
input i_dbg_stpcyl,


output reg [ 31: 0 ] o_minstret_l,//输出mintret寄存器,低32位
output reg [ 31: 0 ] o_minstret_h,//输出minstreth寄存器,高32位


wire dbg_stop = i_dbg_mode & i_dbg_stpcyl;//调试开始
always@( posedge sys_clk or negedge rst_n )
if ( !rst_n )//如果没有复位
begin
    o_minstret_l <= 32'b0;
    o_minstret_h <= 32'b0;
end
else if ( i_csr_wen )//CSR寄存器可写
begin
    case ( i_csr_addr )//CSR指令写入,根据地址索引到低位/高位寄存器
    12'hb02: o_minstret_l <= i_csr_val;
    12'hb82: o_minstret_h <= i_csr_val;
    default: ;
    endcase
end
else if ( ( i_EXE_vld ) && ( dbg_stop == 1'b0 ) )//如果不处于调试,且在执行阶段
begin
    if ( o_minstret_l == 32'hffff_ffff )//如果低32位寄存器已满
    begin
        o_minstret_l <= 0;
        o_minstret_h <= o_minstret_h + 1;//高位进位
    end
    else
        o_minstret_l <= o_minstret_l + 1;//低32位的寄存器加1
end

 

 

Posted in RISC-V, RISC-V IPcore设计, RISC-V 教案, 应用开发, 教材与教案, 文章

发表评论

相关链接