E203 蜂鸟 RISC-V处理器代码阅读笔记 之 CPU csr寄存器组 e203_exu_csr.v

这个文章记录了我学习RISC-V蜂鸟E203处理器的学习历程
针对代码的学习,我结合自己的理解对每个module的接口,以及内部关键信号做了详细的注释说明
原创不易,请保护版权,须转载请私信通知联系作者,并请注明出处,标出原始链接,谢谢~~~
e203_exu_regfile.v

 /*                                                                      
 Copyright 2017 Silicon Integrated Microelectronics, Inc.                
                                                                         
 Licensed under the Apache License, Version 2.0 (the "License");         
 you may not use this file except in compliance with the License.        
 You may obtain a copy of the License at                                 
                                                                         
     http://www.apache.org/licenses/LICENSE-2.0                          
                                                                         
  Unless required by applicable law or agreed to in writing, software    
 distributed under the License is distributed on an "AS IS" BASIS,       
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and     
 limitations under the License.                                          
 */                                                                      
                                                                         
                                                                         
                                                                         
//=====================================================================
//--        _______   ___
//--       (   ____/ /__/
//--        \ \     __
//--     ____\ \   / /
//--    /_______\ /_/   MICROELECTRONICS
//--
//=====================================================================
//
// Designer   : Bob Hu
//
// Description:
//  The module to implement the core's CSRs
//
// ====================================================================
`include "e203_defines.v"

module e203_exu_csr(
  input nonflush_cmt_ena, // 这个信号只有输入,但是啥也没干啊???
  output eai_xs_off, // 固定接了0,跟协处理器相关,具体是干啥的留待后面考证???

  input csr_ena,  // 来自ALU的CSR读写使能
  input csr_wr_en, // 写指示
  input csr_rd_en, // 读指示
  input [12-1:0] csr_idx, //csr寄存器的地址索引

  output csr_access_ilgl, //固定接1'b0
  output tm_stop,         //自定义的配置寄存器的配置信息相应位段的输出,停止timer计数指示信号    
  output core_cgstop,     //停止cpu core逻辑的clk gating
  output tcm_cgstop,      //停止TCM clk gating
  output itcm_nohold,     //itcm 不hold数据的指示信号
  output mdv_nob2b,       //mul/div 不采用back2back特性的指示信号


  output [`E203_XLEN-1:0] read_csr_dat,  //从csr中读出的数据
  input  [`E203_XLEN-1:0] wbck_csr_dat,  //将要写入csr寄存器中的数据
   
  input  [`E203_HART_ID_W-1:0] core_mhartid,
  input  ext_irq_r,  // 中断请求,用于更新中断pending寄存器中的标志位
  input  sft_irq_r,
  input  tmr_irq_r,

  output status_mie_r, // mstatus寄存器中的mie状态
  output mtie_r,       // mie 寄存器中的tie状态
  output msie_r,       // mie 寄存器中的sie状态
  output meie_r,       // mie 寄存器中的eie状态

  output wr_dcsr_ena    , // debug 模式更新 dcsr寄存器的指示信号
  output wr_dpc_ena     ,// debug 模式更新 dpc寄存器的指示信号
  output wr_dscratch_ena,// debug 模式更新 dscratch寄存器的指示信号


  input [`E203_XLEN-1:0] dcsr_r    ,    // debug 模式下的csr的值
  input [`E203_PC_SIZE-1:0] dpc_r     , // debug 模式下的pc的值
  input [`E203_XLEN-1:0] dscratch_r,    // debug 模式下的scratch的值

  output [`E203_XLEN-1:0] wr_csr_nxt    , // 这个就是直接接了wbck_csr_dat 是要写入到csr寄存器中的数据,又做了个输出,暂时不清楚这个信号给谁用了???

  input  dbg_mode, // cpu处于debug模式
  input  dbg_stopcycle, // debug模式下是否停止cpu的时钟周期计数器

  output u_mode, // 当前cpu所处的模式
  output s_mode,
  output h_mode,
  output m_mode, // 只有m_mode为1,其余mode均为0,E203只支持m_mode

  input [`E203_ADDR_SIZE-1:0] cmt_badaddr, // 
  input cmt_badaddr_ena,                   // 如果交付的时候发现时错误指令,那么在cmt_badaddr_ena有效的时候,要把mbadaddr的值更新为cmt_badaddr
  input [`E203_PC_SIZE-1:0] cmt_epc,
  input cmt_epc_ena,  //如果cmt_epc_ena有效,那么需要把mepc寄存器的值更新为cmt_ept
  input [`E203_XLEN-1:0] cmt_cause, //如果指令commit的时候需要记录cause,即cmt_cause_ena有效的时候需要将mcause的值更新为cmt_cause
  input cmt_cause_ena,
  input cmt_status_ena,             //mstatus寄存器的更新指示信号
  input cmt_instret_ena,            //minstret寄存器更新信号,表示一条指令commit了,那么指令个数统计计数器加1

  input                      cmt_mret_ena, //这个信号应该是表示mret指令交付了;具体可以待看了commit的实现再来回看???mret是异常返回指令
  output[`E203_PC_SIZE-1:0]  csr_epc_r,    //输出相应的异常状态下用的pc值
  output[`E203_PC_SIZE-1:0]  csr_dpc_r,
  output[`E203_XLEN-1:0]     csr_mtvec_r,


  input  clk_aon, // always-on clock 即此时钟总是开着的,不会被门控
  input  clk,
  input  rst_n

  );



assign csr_access_ilgl = 1'b0
                ;

// Only toggle when need to read or write to save power
wire wbck_csr_wen = csr_wr_en & csr_ena & (~csr_access_ilgl);  // csr写使能
wire read_csr_ena = csr_rd_en & csr_ena & (~csr_access_ilgl);  // csr读使能

wire [1:0] priv_mode = u_mode ? 2'b00 :   // 生成根据cpu运行的模式生成特权类型
                       s_mode ? 2'b01 :
                       h_mode ? 2'b10 : 
                       m_mode ? 2'b11 : 
                                2'b11;

//0x000 URW ustatus User status register.
//    * Since we support the user-level interrupt, hence we need to support UIE
//0x300 MRW mstatus Machine status register.
wire sel_ustatus = (csr_idx == 12'h000); // 12’h000是ustatus寄存器
wire sel_mstatus = (csr_idx == 12'h300); // 12'h300是mstatus寄存器

wire rd_ustatus = sel_ustatus & csr_rd_en; // 生成寄存器的读写信号
wire rd_mstatus = sel_mstatus & csr_rd_en; 
wire wr_ustatus = sel_ustatus & csr_wr_en;
wire wr_mstatus = sel_mstatus & csr_wr_en;


/
// Note: the below implementation only apply to Machine-mode config,
//       if other mode is also supported, these logics need to be updated

//
// Implement MPIE field
//
wire status_mpie_r; // machine prefer interrupt enable  // machine mode 之前的interrupt enable 状态 
    // The MPIE Feilds will be updates when: 
wire status_mpie_ena  = 
        // The CSR is written by CSR instructions
        (wr_mstatus & wbck_csr_wen) |        // 写mstatus寄存器
        // The MRET instruction commited
        cmt_mret_ena |                       // 处理器在执行了mret指令从异常退出的时候需要同时更新mstatus域中的mpie域
        // The Trap is taken
        cmt_status_ena;                      // 当处理器进入trap时,不管是exception还是interrupt都需要更新mstatus寄存器

wire status_mpie_nxt    = 
    //   See Priv SPEC: // 看特权文档
    //       When a trap is taken from privilege mode y into privilege
    //       mode x, xPIE is set to the value of xIE;
    // So, When the Trap is taken, the MPIE is updated with the current MIE value
    cmt_status_ena ? status_mie_r : //如果是进入trap,那么更新成mie,相当于是保存进入trap前的mie的状态
    //   See Priv SPEC:
    //       When executing an xRET instruction, supposing xPP holds the value y, xIE
    //       is set to xPIE; the privilege mode is changed to y; 
    //       xPIE is set to 1;
    // So, When the MRET instruction commited, the MPIE is updated with 1
    cmt_mret_ena  ? 1'b1 : //当mret指令交付,即从trap中返回的时候MPIE更新成1
    // When the CSR is written by CSR instructions
    (wr_mstatus & wbck_csr_wen) ? wbck_csr_dat[7] : // MPIE is in field 7 of mstatus // 如果是写指令要求写入mstatus的值,那么用待写入的值写mpie
                  status_mpie_r; // Unchanged       // 没有以上情况时mpie保持不变

sirv_gnrl_dfflr #(1) status_mpie_dfflr (status_mpie_ena, status_mpie_nxt, status_mpie_r, clk, rst_n);

//
// Implement MIE field
//
    // The MIE Feilds will be updates same as MPIE
wire status_mie_ena  = status_mpie_ena; 
wire status_mie_nxt    = 
    //   See Priv SPEC:
    //       When a trap is taken from privilege mode y into privilege
    //       mode x, xPIE is set to the value of xIE,
    //       xIE is set to 0;
    // So, When the Trap is taken, the MIE is updated with 0
     cmt_status_ena ? 1'b0 : // 当进入trap的时候,mie更新为0,我理解就是既然trap了,那mie就要关掉,防止再来一个trap状态就乱了,相关的概念可以了解一下中断嵌套
    //   See Priv SPEC:      // 这里可以简单的理解成,既然从原来的那个层面trap到另外一个层面,就不能允许原来那个层面继续被trap
    //       When executing an xRET instruction, supposing xPP holds the value y, xIE
    //       is set to xPIE; the privilege mode is changed to y, xPIE is set to 1;
    // So, When the MRET instruction commited, the MIE is updated with MPIE
    cmt_mret_ena ? status_mpie_r : // 如果从trap回来了,那么mie要更新成mpie的值,即进入trap前通过mpie保存的mie的trap前的值
    // When the CSR is written by CSR instructions
    (wr_mstatus & wbck_csr_wen) ? wbck_csr_dat[3] : // MIE is in field 3 of mstatus //如果是写指令写这个bit那就更新成写入值
                  status_mie_r; // Unchanged 

sirv_gnrl_dfflr #(1) status_mie_dfflr (status_mie_ena, status_mie_nxt, status_mie_r, clk, rst_n);

//
// Implement SD field
//
//  See Priv SPEC:
//    The SD bit is read-only 
//    And is set when either the FS or XS bits encode a Dirty
//      state (i.e., SD=((FS==11) OR (XS==11))).
wire [1:0] status_fs_r;
wire [1:0] status_xs_r;
wire status_sd_r = (status_fs_r == 2'b11) | (status_xs_r == 2'b11); // mstatus的fs域或xs域处于dirty状态的时候

//
// Implement XS field
//
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值