查看: 1144|回复: 0
收起左侧

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

[复制链接]

  离线 

  • TA的每日心情
    奋斗
    2021-3-3 12:32
  • 签到天数: 10 天

    [LV.3]

    发表于 2020-8-24 11:32:13 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 皋陶 于 2020-8-27 13:54 编辑

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

    这个文章记录了我学习RISC-V蜂鸟E203处理器的学习历程

    针对代码的学习,我结合自己的理解对每个module的接口,以及内部关键信号做了详细的注释说明


    原创不易,请保护版权,须转载请私信通知联系作者,并请注明出处,标出原始链接,谢谢~~~


    e203_exu_regfile.v

    1. /*                                                                     
    2. Copyright 2017 Silicon Integrated Microelectronics, Inc.               
    3.                                                                         
    4. Licensed under the Apache License, Version 2.0 (the "License");         
    5. you may not use this file except in compliance with the License.        
    6. You may obtain a copy of the License at                                 
    7.                                                                         
    8.      http://www.apache.org/licenses/LICENSE-2.0                          
    9.                                                                         
    10.   Unless required by applicable law or agreed to in writing, software   
    11. distributed under the License is distributed on an "AS IS" BASIS,      
    12. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13. See the License for the specific language governing permissions and     
    14. limitations under the License.                                          
    15. */                                                                     
    16.                                                                         
    17.                                                                         
    18.                                                                         
    19. //=====================================================================
    20. //--        _______   ___
    21. //--       (   ____/ /__/
    22. //--        \ \     __
    23. //--     ____\ \   / /
    24. //--    /_______\ /_/   MICROELECTRONICS
    25. //--
    26. //=====================================================================
    27. //
    28. // Designer   : Bob Hu
    29. //
    30. // Description:
    31. //  The module to implement the core's CSRs
    32. //
    33. // ====================================================================
    34. `include "e203_defines.v"

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

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

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


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

    55.   output status_mie_r, // mstatus寄存器中的mie状态
    56.   output mtie_r,       // mie 寄存器中的tie状态
    57.   output msie_r,       // mie 寄存器中的sie状态
    58.   output meie_r,       // mie 寄存器中的eie状态

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


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

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

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

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

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

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


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

    87.   );



    88. assign csr_access_ilgl = 1'b0
    89.                 ;

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

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

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

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


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

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

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

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

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

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

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

    169. //
    170. // Implement XS field
    171. //
    172. //  See Priv SPEC:
    173. //    XS field is read-only
    174. //    The XS field represents a summary of all extensions' status
    175.     // But in E200 we implement XS exactly same as FS to make it usable by software to
    176.     //   disable extended accelerators
    177. `ifndef E203_HAS_EAI
    178.    // If no EAI coprocessor interface configured, the XS is just hardwired to 0
    179. assign status_xs_r = 2'b0;
    180. assign eai_xs_off = 1'b0;// We just make this signal to 0
    181. `endif

    182. //
    183. // Implement FS field
    184. //

    185. `ifndef E203_HAS_FPU
    186.    // If no FPU configured, the FS is just hardwired to 0
    187. assign status_fs_r = 2'b0;
    188. `endif

    189. //
    190. // Pack to the full mstatus register
    191. //
    192. wire [`E203_XLEN-1:0] status_r;
    193. assign status_r[31]    = status_sd_r;                        //SD
    194. assign status_r[30:23] = 8'b0; // Reserved
    195. assign status_r[22:17] = 6'b0;               // TSR--MPRV
    196. assign status_r[16:15] = status_xs_r;                        // XS
    197. assign status_r[14:13] = status_fs_r;                        // FS
    198. assign status_r[12:11] = 2'b11;              // MPP
    199. assign status_r[10:9]  = 2'b0; // Reserved
    200. assign status_r[8]     = 1'b0;               // SPP
    201. assign status_r[7]     = status_mpie_r;                      // MPIE
    202. assign status_r[6]     = 1'b0; // Reserved
    203. assign status_r[5]     = 1'b0;               // SPIE
    204. assign status_r[4]     = 1'b0;               // UPIE
    205. assign status_r[3]     = status_mie_r;                       // MIE
    206. assign status_r[2]     = 1'b0; // Reserved
    207. assign status_r[1]     = 1'b0;               // SIE
    208. assign status_r[0]     = 1'b0;               // UIE

    209. wire [`E203_XLEN-1:0] csr_mstatus = status_r;

    210. //0x004 URW uie User interrupt-enable register.
    211. //    * Since we dont delegate interrupt to user mode, hence it is as all 0s
    212. //0x304 MRW mie Machine interrupt-enable register.
    213. wire sel_mie = (csr_idx == 12'h304); //0x304是mie寄存器,mie寄存器用于控制不同中断类型的局部屏蔽;注意跟mstatus寄存器中的mie位段不是一个东西,这个是一个完整的reg
    214. wire rd_mie = sel_mie & csr_rd_en;   //生成mie的读写使能
    215. wire wr_mie = sel_mie & csr_wr_en;
    216. wire mie_ena = wr_mie & wbck_csr_wen;
    217. wire [`E203_XLEN-1:0] mie_r;
    218. wire [`E203_XLEN-1:0] mie_nxt;
    219. assign mie_nxt[31:12] = 20'b0;
    220. assign mie_nxt[11] = wbck_csr_dat[11];//MEIE  //这个是个单纯的配置寄存器,只存在cpu指令配置的情况,所以nxt只有cpu指令的写入值
    221. assign mie_nxt[10:8] = 3'b0;
    222. assign mie_nxt[ 7] = wbck_csr_dat[ 7];//MTIE
    223. assign mie_nxt[6:4] = 3'b0;
    224. assign mie_nxt[ 3] = wbck_csr_dat[ 3];//MSIE
    225. assign mie_nxt[2:0] = 3'b0;
    226. sirv_gnrl_dfflr #(`E203_XLEN) mie_dfflr (mie_ena, mie_nxt, mie_r, clk, rst_n);
    227. wire [`E203_XLEN-1:0] csr_mie = mie_r;

    228. assign meie_r = csr_mie[11];
    229. assign mtie_r = csr_mie[ 7];
    230. assign msie_r = csr_mie[ 3];

    231. //0x044 URW uip User interrupt pending.
    232. //  We dont support delegation scheme, so no need to support the uip
    233. //0x344 MRW mip Machine interrupt pending
    234. wire sel_mip = (csr_idx == 12'h344); // 12'h344地址为mip寄存器,用于指示中断的pending状态
    235. wire rd_mip = sel_mip & csr_rd_en;
    236. //wire wr_mip = sel_mip & csr_wr_en;
    237. // The MxIP is read-only
    238. wire meip_r;
    239. wire msip_r;
    240. wire mtip_r;
    241. sirv_gnrl_dffr #(1) meip_dffr (ext_irq_r, meip_r, clk, rst_n);  // 这三个是mip中的三个有效的bit,只读的 exception interrupt pending
    242. sirv_gnrl_dffr #(1) msip_dffr (sft_irq_r, msip_r, clk, rst_n);  // software interrupt pending
    243. sirv_gnrl_dffr #(1) mtip_dffr (tmr_irq_r, mtip_r, clk, rst_n);  // trap interrupt pending

    244. wire [`E203_XLEN-1:0] ip_r;
    245. assign ip_r[31:12] = 20'b0;
    246. assign ip_r[11] = meip_r;
    247. assign ip_r[10:8] = 3'b0;
    248. assign ip_r[ 7] = mtip_r;
    249. assign ip_r[6:4] = 3'b0;
    250. assign ip_r[ 3] = msip_r;
    251. assign ip_r[2:0] = 3'b0;
    252. wire [`E203_XLEN-1:0] csr_mip = ip_r;
    253. //

    254. //0x005 URW utvec User trap handler base address.
    255. //  We dont support user trap, so no utvec needed
    256. //0x305 MRW mtvec Machine trap-handler base address.
    257. wire sel_mtvec = (csr_idx == 12'h305); // 12'h305是mtvec寄存器,trap-handler的基地址,就是我们常说的中断向量的基地址
    258. wire rd_mtvec = csr_rd_en & sel_mtvec;
    259. `ifdef E203_SUPPORT_MTVEC //{
    260. wire wr_mtvec = sel_mtvec & csr_wr_en;
    261. wire mtvec_ena = (wr_mtvec & wbck_csr_wen);
    262. wire [`E203_XLEN-1:0] mtvec_r;
    263. wire [`E203_XLEN-1:0] mtvec_nxt = wbck_csr_dat;
    264. sirv_gnrl_dfflr #(`E203_XLEN) mtvec_dfflr (mtvec_ena, mtvec_nxt, mtvec_r, clk, rst_n);
    265. wire [`E203_XLEN-1:0] csr_mtvec = mtvec_r;
    266. `else//}{
    267.   // THe vector table base is a configurable parameter, so we dont support writeable to it
    268. wire [`E203_XLEN-1:0] csr_mtvec = `E203_MTVEC_TRAP_BASE;  // 因为E203这里采用了宏定义的方式设置mtvec,所以直接就不支持软件设置了
    269. `endif//}
    270. assign csr_mtvec_r = csr_mtvec;

    271. //0x340 MRW mscratch
    272. wire sel_mscratch = (csr_idx == 12'h340); //12'h304是mscratch寄存器,用于在机器模式下快速保存一些配置,用于快速回复现场
    273. wire rd_mscratch = sel_mscratch & csr_rd_en;
    274. `ifdef E203_SUPPORT_MSCRATCH //{
    275. wire wr_mscratch = sel_mscratch & csr_wr_en;
    276. wire mscratch_ena = (wr_mscratch & wbck_csr_wen);
    277. wire [`E203_XLEN-1:0] mscratch_r;
    278. wire [`E203_XLEN-1:0] mscratch_nxt = wbck_csr_dat;
    279. sirv_gnrl_dfflr #(`E203_XLEN) mscratch_dfflr (mscratch_ena, mscratch_nxt, mscratch_r, clk, rst_n);
    280. wire [`E203_XLEN-1:0] csr_mscratch = mscratch_r;
    281. `else//}{
    282. wire [`E203_XLEN-1:0] csr_mscratch = `E203_XLEN'b0;
    283. `endif//}

    284. // 0xB00 MRW mcycle
    285. // 0xB02 MRW minstret
    286. // 0xB80 MRW mcycleh
    287. // 0xB82 MRW minstreth
    288. wire sel_mcycle    = (csr_idx == 12'hB00); //12'hB00 是mcycle寄存器,用于记录处理器执行了多少个时钟周期的64位计数器的低32bit
    289. wire sel_mcycleh   = (csr_idx == 12'hB80); //12'hB80 是mcycleh寄存器                                                 高32bit
    290. wire sel_minstret  = (csr_idx == 12'hB02); //12'hB02 is lower 32bits of instructions-retired counter(记录成功执行了多少指令)
    291. wire sel_minstreth = (csr_idx == 12'hB82); //12'hB82 is upper 32bits of instructions-retired counter(记录成功执行了多少指令)

    292. // 0xBFF MRW counterstop   由于上面两个counter都是用于统计cpu性能的,所以当不用统计的时候,给他关掉以节省动态功耗;
    293.       // This register is our self-defined register to stop               因此自定义了一个mcounterstop寄存器用于控制mcycle和minstret的计数开关
    294.       // the cycle/time/instret counters to save dynamic powers
    295. wire sel_counterstop = (csr_idx == 12'hBFF);// This address is not used by ISA
    296. // 0xBFE MRW mcgstop
    297.       // This register is our self-defined register to disable the
    298.       // automaticall clock gating for CPU logics for debugging purpose
    299. wire sel_mcgstop = (csr_idx == 12'hBFE);// This address is not used by ISA 自定义的mcgstop寄存器,用于关闭cpu逻辑的时钟门控???
    300. // 0xBFD MRW itcmnohold
    301.       // This register is our self-defined register to disble the
    302.       // ITCM SRAM output holdup feature, if set, then we assume
    303.       // ITCM SRAM output cannot holdup last read value
    304. wire sel_itcmnohold = (csr_idx == 12'hBFD);// This address is not used by ISA 自定义的mitcmnohold,用于配置itcm是否要保持住数据
    305. // 0xBF0 MRW mdvnob2b
    306.       // This register is our self-defined register to disble the
    307.       // Mul/div back2back feature
    308. wire sel_mdvnob2b = (csr_idx == 12'hBF0);// This address is not used by ISA 自定义的mdvnob2b 用于配置乘除操作是否开启back2back特性


    309. wire rd_mcycle     = csr_rd_en & sel_mcycle   ;
    310. wire rd_mcycleh    = csr_rd_en & sel_mcycleh  ;
    311. wire rd_minstret   = csr_rd_en & sel_minstret ;
    312. wire rd_minstreth  = csr_rd_en & sel_minstreth;

    313. wire rd_itcmnohold   = csr_rd_en & sel_itcmnohold;
    314. wire rd_mdvnob2b   = csr_rd_en & sel_mdvnob2b;
    315. wire rd_counterstop  = csr_rd_en & sel_counterstop;
    316. wire rd_mcgstop       = csr_rd_en & sel_mcgstop;

    317. `ifdef E203_SUPPORT_MCYCLE_MINSTRET //{
    318. wire wr_mcycle     = csr_wr_en & sel_mcycle   ;
    319. wire wr_mcycleh    = csr_wr_en & sel_mcycleh  ;
    320. wire wr_minstret   = csr_wr_en & sel_minstret ;
    321. wire wr_minstreth  = csr_wr_en & sel_minstreth;

    322. wire wr_itcmnohold   = csr_wr_en & sel_itcmnohold ;
    323. wire wr_mdvnob2b   = csr_wr_en & sel_mdvnob2b ;
    324. wire wr_counterstop  = csr_wr_en & sel_counterstop;
    325. wire wr_mcgstop       = csr_wr_en & sel_mcgstop     ;

    326. wire mcycle_wr_ena    = (wr_mcycle    & wbck_csr_wen);
    327. wire mcycleh_wr_ena   = (wr_mcycleh   & wbck_csr_wen);
    328. wire minstret_wr_ena  = (wr_minstret  & wbck_csr_wen);
    329. wire minstreth_wr_ena = (wr_minstreth & wbck_csr_wen);

    330. wire itcmnohold_wr_ena  = (wr_itcmnohold  & wbck_csr_wen);
    331. wire mdvnob2b_wr_ena  = (wr_mdvnob2b  & wbck_csr_wen);
    332. wire counterstop_wr_ena = (wr_counterstop & wbck_csr_wen);
    333. wire mcgstop_wr_ena      = (wr_mcgstop      & wbck_csr_wen);

    334. wire [`E203_XLEN-1:0] mcycle_r   ;
    335. wire [`E203_XLEN-1:0] mcycleh_r  ;
    336. wire [`E203_XLEN-1:0] minstret_r ;
    337. wire [`E203_XLEN-1:0] minstreth_r;

    338. wire cy_stop;
    339. wire ir_stop;

    340. wire stop_cycle_in_dbg = dbg_stopcycle & dbg_mode; //debug模式下停止时钟模式计数
    341. wire mcycle_ena    = mcycle_wr_ena    |
    342.                      ((~cy_stop) & (~stop_cycle_in_dbg) & (1'b1)); //如果是cpu写,或者是循序cycle计数的时候,计数寄存器更新使能
    343. wire mcycleh_ena   = mcycleh_wr_ena   |
    344.                      ((~cy_stop) & (~stop_cycle_in_dbg) & ((mcycle_r == (~(`E203_XLEN'b0))))); //如果是cpu写,计数使能且低32bit计数为全1;
    345. wire minstret_ena  = minstret_wr_ena  |
    346.                      ((~ir_stop) & (~stop_cycle_in_dbg) & (cmt_instret_ena)); //cpu写,且允许指令计数,且指令被commit了,计数加1
    347. wire minstreth_ena = minstreth_wr_ena |
    348.                      ((~ir_stop) & (~stop_cycle_in_dbg) & ((cmt_instret_ena & (minstret_r == (~(`E203_XLEN'b0))))));//cpu写,且允许指令计数,且指令被commit了,且低32bit为全1,计数加1

    349. wire [`E203_XLEN-1:0] mcycle_nxt    = mcycle_wr_ena    ? wbck_csr_dat : (mcycle_r    + 1'b1);
    350. wire [`E203_XLEN-1:0] mcycleh_nxt   = mcycleh_wr_ena   ? wbck_csr_dat : (mcycleh_r   + 1'b1);
    351. wire [`E203_XLEN-1:0] minstret_nxt  = minstret_wr_ena  ? wbck_csr_dat : (minstret_r  + 1'b1);
    352. wire [`E203_XLEN-1:0] minstreth_nxt = minstreth_wr_ena ? wbck_csr_dat : (minstreth_r + 1'b1);

    353. //We need to use the always-on clock for this counter
    354. sirv_gnrl_dfflr #(`E203_XLEN) mcycle_dfflr (mcycle_ena, mcycle_nxt, mcycle_r   , clk_aon, rst_n);
    355. sirv_gnrl_dfflr #(`E203_XLEN) mcycleh_dfflr (mcycleh_ena, mcycleh_nxt, mcycleh_r  , clk_aon, rst_n);
    356. sirv_gnrl_dfflr #(`E203_XLEN) minstret_dfflr (minstret_ena, minstret_nxt, minstret_r , clk, rst_n);
    357. sirv_gnrl_dfflr #(`E203_XLEN) minstreth_dfflr (minstreth_ena, minstreth_nxt, minstreth_r, clk, rst_n);

    358. wire [`E203_XLEN-1:0] counterstop_r;
    359. wire counterstop_ena = counterstop_wr_ena;
    360. wire [`E203_XLEN-1:0] counterstop_nxt = {29'b0,wbck_csr_dat[2:0]};// Only LSB 3bits are useful
    361. sirv_gnrl_dfflr #(`E203_XLEN) counterstop_dfflr (counterstop_ena, counterstop_nxt, counterstop_r, clk, rst_n);

    362. wire [`E203_XLEN-1:0] csr_mcycle    = mcycle_r;
    363. wire [`E203_XLEN-1:0] csr_mcycleh   = mcycleh_r;
    364. wire [`E203_XLEN-1:0] csr_minstret  = minstret_r;
    365. wire [`E203_XLEN-1:0] csr_minstreth = minstreth_r;
    366. wire [`E203_XLEN-1:0] csr_counterstop = counterstop_r;
    367. `else//}{
    368. wire [`E203_XLEN-1:0] csr_mcycle    = `E203_XLEN'b0;
    369. wire [`E203_XLEN-1:0] csr_mcycleh   = `E203_XLEN'b0;
    370. wire [`E203_XLEN-1:0] csr_minstret  = `E203_XLEN'b0;
    371. wire [`E203_XLEN-1:0] csr_minstreth = `E203_XLEN'b0;
    372. wire [`E203_XLEN-1:0] csr_counterstop = `E203_XLEN'b0;
    373. `endif//}

    374. wire [`E203_XLEN-1:0] itcmnohold_r; // itcmnohold是一个单纯的cpu配置寄存器
    375. wire itcmnohold_ena = itcmnohold_wr_ena;
    376. wire [`E203_XLEN-1:0] itcmnohold_nxt = {31'b0,wbck_csr_dat[0]};// Only LSB 1bits are useful
    377. sirv_gnrl_dfflr #(`E203_XLEN) itcmnohold_dfflr (itcmnohold_ena, itcmnohold_nxt, itcmnohold_r, clk, rst_n);

    378. wire [`E203_XLEN-1:0] csr_itcmnohold  = itcmnohold_r;

    379. wire [`E203_XLEN-1:0] mdvnob2b_r; // mdvnob2b也是一个单纯的cpu配置寄存器
    380. wire mdvnob2b_ena = mdvnob2b_wr_ena;
    381. wire [`E203_XLEN-1:0] mdvnob2b_nxt = {31'b0,wbck_csr_dat[0]};// Only LSB 1bits are useful
    382. sirv_gnrl_dfflr #(`E203_XLEN) mdvnob2b_dfflr (mdvnob2b_ena, mdvnob2b_nxt, mdvnob2b_r, clk, rst_n);

    383. wire [`E203_XLEN-1:0] csr_mdvnob2b  = mdvnob2b_r;

    384. assign cy_stop = counterstop_r[0];// Stop CYCLE   counter
    385. assign tm_stop = counterstop_r[1];// Stop TIME    counter
    386. assign ir_stop = counterstop_r[2];// Stop INSTRET counter

    387. assign itcm_nohold = itcmnohold_r[0];// ITCM no-hold up feature
    388. assign mdv_nob2b = mdvnob2b_r[0];// Mul/Div no back2back feature



    389. wire [`E203_XLEN-1:0] mcgstop_r;// mcgstop 也是一个单纯的cpu配置寄存器
    390. wire mcgstop_ena = mcgstop_wr_ena;
    391. wire [`E203_XLEN-1:0] mcgstop_nxt = {30'b0,wbck_csr_dat[1:0]};// Only LSB 2bits are useful
    392. sirv_gnrl_dfflr #(`E203_XLEN) mcgstop_dfflr (mcgstop_ena, mcgstop_nxt, mcgstop_r, clk, rst_n);
    393. wire [`E203_XLEN-1:0] csr_mcgstop = mcgstop_r;
    394. assign core_cgstop = mcgstop_r[0];// Stop Core clock gating
    395. assign tcm_cgstop = mcgstop_r[1];// Stop TCM  clock gating


    396. //`ifdef E203_SUPPORT_CYCLE //{
    397. 0xC00 URO cycle
    398. 0xC80 URO cycleh
    399. //wire sel_cycle  = (csr_idx == 12'hc00);
    400. //wire sel_cycleh = (csr_idx == 12'hc80);
    401. //wire rd_cycle = sel_cycle & csr_rd_en;
    402. //wire wr_cycle = sel_cycle & csr_wr_en;
    403. //wire cycle_ena = (wr_cycle & wbck_csr_wen);
    404. //wire rd_cycleh = sel_cycleh & csr_rd_en;
    405. //wire wr_cycleh = sel_cycleh & csr_wr_en;
    406. //wire cycleh_ena = (wr_cycleh & wbck_csr_wen);
    407. //wire [`E203_XLEN-1:0] cycle_r;
    408. //wire [`E203_XLEN-1:0] cycleh_r;
    409. //wire [`E203_XLEN-1:0] cycle_nxt = wbck_csr_dat;
    410. //wire [`E203_XLEN-1:0] cycleh_nxt = wbck_csr_dat;
    411. //sirv_gnrl_dfflr #(`E203_XLEN) cycle_dfflr (cycle_ena, cycle_nxt, cycle_r, clk, rst_n);
    412. //sirv_gnrl_dfflr #(`E203_XLEN) cycleh_dfflr(cycleh_ena,cycleh_nxt,cycleh_r,clk, rst_n);
    413. //wire [`E203_XLEN-1:0] csr_cycle  = cycle_r;
    414. //wire [`E203_XLEN-1:0] csr_cycleh = cycleh_r;
    415. //`else//}{
    416. //wire [`E203_XLEN-1:0] csr_cycle = `E203_XLEN'b0;
    417. //wire [`E203_XLEN-1:0] csr_cycleh = `E203_XLEN'b0;
    418. //`endif//}

    419. //
    420. //0x041 URW uepc User exception program counter.
    421. //  We dont support user trap, so no uepc needed
    422. //0x341 MRW mepc Machine exception program counter.
    423. wire sel_mepc = (csr_idx == 12'h341);  // mepc 是异常模式下的pc指针
    424. wire rd_mepc = sel_mepc & csr_rd_en;
    425. wire wr_mepc = sel_mepc & csr_wr_en;
    426. wire epc_ena = (wr_mepc & wbck_csr_wen) | cmt_epc_ena;
    427. wire [`E203_PC_SIZE-1:0] epc_r;
    428. wire [`E203_PC_SIZE-1:0] epc_nxt;
    429. assign epc_nxt[`E203_PC_SIZE-1:1] = cmt_epc_ena ? cmt_epc[`E203_PC_SIZE-1:1] : wbck_csr_dat[`E203_PC_SIZE-1:1];
    430. assign epc_nxt[0] = 1'b0;// Must not hold PC which will generate the misalign exception according to ISA
    431. sirv_gnrl_dfflr #(`E203_PC_SIZE) epc_dfflr (epc_ena, epc_nxt, epc_r, clk, rst_n);
    432. wire [`E203_XLEN-1:0] csr_mepc;
    433. wire dummy_0;
    434. assign {dummy_0,csr_mepc} = {{`E203_XLEN+1-`E203_PC_SIZE{1'b0}},epc_r};
    435. assign csr_epc_r = csr_mepc;

    436. //0x042 URW ucause User trap cause.
    437. //  We dont support user trap, so no ucause needed
    438. //0x342 MRW mcause Machine trap cause.
    439. wire sel_mcause = (csr_idx == 12'h342); //12'h342 mcause 用于保存进入异常之前出错的原因,以便与对异常原因进行诊断和调试
    440. wire rd_mcause = sel_mcause & csr_rd_en;
    441. wire wr_mcause = sel_mcause & csr_wr_en;
    442. wire cause_ena = (wr_mcause & wbck_csr_wen) | cmt_cause_ena; // 如果cpu写,或者指令commit的时候需要记录cause
    443. wire [`E203_XLEN-1:0] cause_r;
    444. wire [`E203_XLEN-1:0] cause_nxt;
    445. assign cause_nxt[31]  = cmt_cause_ena ? cmt_cause[31] : wbck_csr_dat[31];
    446. assign cause_nxt[30:4] = 27'b0;
    447. assign cause_nxt[3:0] = cmt_cause_ena ? cmt_cause[3:0] : wbck_csr_dat[3:0];
    448. sirv_gnrl_dfflr #(`E203_XLEN) cause_dfflr (cause_ena, cause_nxt, cause_r, clk, rst_n);
    449. wire [`E203_XLEN-1:0] csr_mcause = cause_r;


    450. //0x043 URW ubadaddr User bad address.
    451. //  We dont support user trap, so no ubadaddr needed
    452. //0x343 MRW mbadaddr Machine bad address.
    453. wire sel_mbadaddr = (csr_idx == 12'h343);
    454. wire rd_mbadaddr = sel_mbadaddr & csr_rd_en; // 用于记录有问题的指令的地址,跟上面的寄存器一样,要么是cpu主动写入,要么是commit指令的时候写入
    455. wire wr_mbadaddr = sel_mbadaddr & csr_wr_en;
    456. wire cmt_trap_badaddr_ena = cmt_badaddr_ena;
    457. wire badaddr_ena = (wr_mbadaddr & wbck_csr_wen) | cmt_trap_badaddr_ena;
    458. wire [`E203_ADDR_SIZE-1:0] badaddr_r;
    459. wire [`E203_ADDR_SIZE-1:0] badaddr_nxt;
    460. assign badaddr_nxt = cmt_trap_badaddr_ena ? cmt_badaddr : wbck_csr_dat[`E203_ADDR_SIZE-1:0];
    461. sirv_gnrl_dfflr #(`E203_ADDR_SIZE) badaddr_dfflr (badaddr_ena, badaddr_nxt, badaddr_r, clk, rst_n);
    462. wire [`E203_XLEN-1:0] csr_mbadaddr;
    463. wire dummy_1;
    464. assign {dummy_1,csr_mbadaddr} = {{`E203_XLEN+1-`E203_ADDR_SIZE{1'b0}},badaddr_r};

    465. // We dont support the delegation scheme, so no need to implement
    466. //   delegete registers


    467. //0x301 MRW misa ISA and extensions
    468. wire sel_misa = (csr_idx == 12'h301);  // 12'h301 misa寄存器,只读的寄存器,用于指示当前寄存器所支持的架构特性
    469. wire rd_misa = sel_misa & csr_rd_en;
    470. // Only implemented the M mode, IMC or EMC
    471. wire [`E203_XLEN-1:0] csr_misa = {
    472.     2'b1
    473.    ,4'b0 //WIRI
    474.    ,1'b0 //              25 Z Reserved
    475.    ,1'b0 //              24 Y Reserved
    476.    ,1'b0 //              23 X Non-standard extensions present
    477.    ,1'b0 //              22 W Reserved
    478.    ,1'b0 //              21 V Tentatively reserved for Vector extension 20 U User mode implemented
    479.    ,1'b0 //              20 U User mode implemented
    480.    ,1'b0 //              19 T Tentatively reserved for Transactional Memory extension
    481.    ,1'b0 //              18 S Supervisor mode implemented
    482.    ,1'b0 //              17 R Reserved
    483.    ,1'b0 //              16 Q Quad-precision floating-point extension
    484.    ,1'b0 //              15 P Tentatively reserved for Packed-SIMD extension
    485.    ,1'b0 //              14 O Reserved
    486.    ,1'b0 //              13 N User-level interrupts supported
    487.    ,1'b1 // 12 M Integer Multiply/Divide extension
    488.    ,1'b0 //              11 L Tentatively reserved for Decimal Floating-Point extension
    489.    ,1'b0 //              10 K Reserved
    490.    ,1'b0 //              9 J Reserved
    491.    `ifdef E203_RFREG_NUM_IS_32
    492.    ,1'b1 // 8 I RV32I/64I/128I base ISA
    493.    `else
    494.    ,1'b0
    495.    `endif
    496.    ,1'b0 //              7 H Hypervisor mode implemented
    497.    ,1'b0 //              6 G Additional standard extensions present
    498.   `ifndef E203_HAS_FPU//{
    499.    ,1'b0 //              5 F Single-precision floating-point extension
    500.   `endif//
    501.    `ifdef E203_RFREG_NUM_IS_32
    502.    ,1'b0 //              4 E RV32E base ISA
    503.    `else
    504.    ,1'b1 //              
    505.    `endif
    506.   `ifndef E203_HAS_FPU//{
    507.    ,1'b0 //              3 D Double-precision floating-point extension
    508.   `endif//
    509.    ,1'b1 // 2 C Compressed extension
    510.    ,1'b0 //              1 B Tentatively reserved for Bit operations extension
    511.   `ifdef E203_SUPPORT_AMO//{
    512.    ,1'b1 //              0 A Atomic extension
    513.   `endif//E203_SUPPORT_AMO}
    514.   `ifndef E203_SUPPORT_AMO//{
    515.    ,1'b0 //              0 A Atomic extension
    516.   `endif//}
    517.                            };

    518. //Machine Information Registers
    519. //0xF11 MRO mvendorid Vendor ID.
    520. //0xF12 MRO marchid Architecture ID.
    521. //0xF13 MRO mimpid Implementation ID.
    522. //0xF14 MRO mhartid Hardware thread ID.
    523. wire [`E203_XLEN-1:0] csr_mvendorid = `E203_XLEN'h`E203_MVENDORID; // vendor ID 寄存器
    524. wire [`E203_XLEN-1:0] csr_marchid   = `E203_XLEN'h`E203_MARCHID  ; // 架构 Id 寄存器
    525. wire [`E203_XLEN-1:0] csr_mimpid    = `E203_XLEN'h`E203_MIMPID   ; // 处理器核的硬件实现编号ID 寄存器
    526. wire [`E203_XLEN-1:0] csr_mhartid   = {{`E203_XLEN-`E203_HART_ID_W{1'b0}},core_mhartid}; // 处理器Hart ID
    527. wire rd_mvendorid = csr_rd_en & (csr_idx == 12'hF11);
    528. wire rd_marchid   = csr_rd_en & (csr_idx == 12'hF12);
    529. wire rd_mimpid    = csr_rd_en & (csr_idx == 12'hF13);
    530. wire rd_mhartid   = csr_rd_en & (csr_idx == 12'hF14);

    531. //0x7b0 Debug Control and Status
    532. //0x7b1 Debug PC
    533. //0x7b2 Debug Scratch Register
    534. //0x7a0 Trigger selection register
    535. wire sel_dcsr     = (csr_idx == 12'h7b0); // debug 模式下的csr( Control and  status register)
    536. wire sel_dpc      = (csr_idx == 12'h7b1); // debug 模式下的PC指针
    537. wire sel_dscratch = (csr_idx == 12'h7b2); // debug 模式下的scratch寄存器,用于临时保存数据,便于恢复现场

    538. wire rd_dcsr     = dbg_mode & csr_rd_en & sel_dcsr    ;
    539. wire rd_dpc      = dbg_mode & csr_rd_en & sel_dpc     ;
    540. wire rd_dscratch = dbg_mode & csr_rd_en & sel_dscratch;


    541. assign wr_dcsr_ena     = dbg_mode & csr_wr_en & sel_dcsr    ;
    542. assign wr_dpc_ena      = dbg_mode & csr_wr_en & sel_dpc     ;
    543. assign wr_dscratch_ena = dbg_mode & csr_wr_en & sel_dscratch;


    544. assign wr_csr_nxt     = wbck_csr_dat;


    545. wire [`E203_XLEN-1:0] csr_dcsr     = dcsr_r    ;
    546. `ifdef E203_PC_SIZE_IS_16
    547. wire [`E203_XLEN-1:0] csr_dpc      = {{`E203_XLEN-`E203_PC_SIZE{1'b0}},dpc_r};
    548. `endif
    549. `ifdef E203_PC_SIZE_IS_24
    550. wire [`E203_XLEN-1:0] csr_dpc      = {{`E203_XLEN-`E203_PC_SIZE{1'b0}},dpc_r};
    551. `endif
    552. `ifdef E203_PC_SIZE_IS_32
    553. wire [`E203_XLEN-1:0] csr_dpc      = dpc_r     ;
    554. `endif
    555. wire [`E203_XLEN-1:0] csr_dscratch = dscratch_r;

    556. assign csr_dpc_r = dpc_r;

    557. /
    558. //  Generate the Read path
    559.   //Currently we only support the M mode to simplify the implementation and
    560.   //      reduce the gatecount because we are a privite core
    561. assign u_mode = 1'b0; // 当前的cpu所处的模式
    562. assign s_mode = 1'b0;
    563. assign h_mode = 1'b0;
    564. assign m_mode = 1'b1;
    565. assign read_csr_dat = `E203_XLEN'b0  // csr寄存器的读通路
    566.                //| ({`E203_XLEN{rd_ustatus  }} & csr_ustatus  )
    567.                | ({`E203_XLEN{rd_mstatus  }} & csr_mstatus  )
    568.                | ({`E203_XLEN{rd_mie      }} & csr_mie      )
    569.                | ({`E203_XLEN{rd_mtvec    }} & csr_mtvec    )
    570.                | ({`E203_XLEN{rd_mepc     }} & csr_mepc     )
    571.                | ({`E203_XLEN{rd_mscratch }} & csr_mscratch )
    572.                | ({`E203_XLEN{rd_mcause   }} & csr_mcause   )
    573.                | ({`E203_XLEN{rd_mbadaddr }} & csr_mbadaddr )
    574.                | ({`E203_XLEN{rd_mip      }} & csr_mip      )
    575.                | ({`E203_XLEN{rd_misa     }} & csr_misa      )
    576.                | ({`E203_XLEN{rd_mvendorid}} & csr_mvendorid)
    577.                | ({`E203_XLEN{rd_marchid  }} & csr_marchid  )
    578.                | ({`E203_XLEN{rd_mimpid   }} & csr_mimpid   )
    579.                | ({`E203_XLEN{rd_mhartid  }} & csr_mhartid  )
    580.                | ({`E203_XLEN{rd_mcycle   }} & csr_mcycle   )
    581.                | ({`E203_XLEN{rd_mcycleh  }} & csr_mcycleh  )
    582.                | ({`E203_XLEN{rd_minstret }} & csr_minstret )
    583.                | ({`E203_XLEN{rd_minstreth}} & csr_minstreth)
    584.                | ({`E203_XLEN{rd_counterstop}} & csr_counterstop)// Self-defined
    585.                | ({`E203_XLEN{rd_mcgstop}} & csr_mcgstop)// Self-defined
    586.                | ({`E203_XLEN{rd_itcmnohold}} & csr_itcmnohold)// Self-defined
    587.                | ({`E203_XLEN{rd_mdvnob2b}} & csr_mdvnob2b)// Self-defined
    588.                | ({`E203_XLEN{rd_dcsr     }} & csr_dcsr    )
    589.                | ({`E203_XLEN{rd_dpc      }} & csr_dpc     )
    590.                | ({`E203_XLEN{rd_dscratch }} & csr_dscratch)
    591.                ;

    复制代码

    本篇完,感谢关注:RISC-V单片机中文网




    上一篇:CKB-VM:连接硬件和软件的桥梁——Nervos@RISC-V Roadshow
    下一篇:RISC-V处理器:1.取指令 RTL 代码分析
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-3-29 04:07 , Processed in 0.415320 second(s), 45 queries .

    快速回复 返回顶部 返回列表