离线
TA的每日心情 | 奋斗 2021-3-3 12:32 |
---|
签到天数: 10 天 [LV.3]
|
有人预言,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
- /*
- 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
- //
- // See Priv SPEC:
- // XS field is read-only
- // The XS field represents a summary of all extensions' status
- // But in E200 we implement XS exactly same as FS to make it usable by software to
- // disable extended accelerators
- `ifndef E203_HAS_EAI
- // If no EAI coprocessor interface configured, the XS is just hardwired to 0
- assign status_xs_r = 2'b0;
- assign eai_xs_off = 1'b0;// We just make this signal to 0
- `endif
- //
- // Implement FS field
- //
- `ifndef E203_HAS_FPU
- // If no FPU configured, the FS is just hardwired to 0
- assign status_fs_r = 2'b0;
- `endif
- //
- // Pack to the full mstatus register
- //
- wire [`E203_XLEN-1:0] status_r;
- assign status_r[31] = status_sd_r; //SD
- assign status_r[30:23] = 8'b0; // Reserved
- assign status_r[22:17] = 6'b0; // TSR--MPRV
- assign status_r[16:15] = status_xs_r; // XS
- assign status_r[14:13] = status_fs_r; // FS
- assign status_r[12:11] = 2'b11; // MPP
- assign status_r[10:9] = 2'b0; // Reserved
- assign status_r[8] = 1'b0; // SPP
- assign status_r[7] = status_mpie_r; // MPIE
- assign status_r[6] = 1'b0; // Reserved
- assign status_r[5] = 1'b0; // SPIE
- assign status_r[4] = 1'b0; // UPIE
- assign status_r[3] = status_mie_r; // MIE
- assign status_r[2] = 1'b0; // Reserved
- assign status_r[1] = 1'b0; // SIE
- assign status_r[0] = 1'b0; // UIE
- wire [`E203_XLEN-1:0] csr_mstatus = status_r;
- //0x004 URW uie User interrupt-enable register.
- // * Since we dont delegate interrupt to user mode, hence it is as all 0s
- //0x304 MRW mie Machine interrupt-enable register.
- wire sel_mie = (csr_idx == 12'h304); //0x304是mie寄存器,mie寄存器用于控制不同中断类型的局部屏蔽;注意跟mstatus寄存器中的mie位段不是一个东西,这个是一个完整的reg
- wire rd_mie = sel_mie & csr_rd_en; //生成mie的读写使能
- wire wr_mie = sel_mie & csr_wr_en;
- wire mie_ena = wr_mie & wbck_csr_wen;
- wire [`E203_XLEN-1:0] mie_r;
- wire [`E203_XLEN-1:0] mie_nxt;
- assign mie_nxt[31:12] = 20'b0;
- assign mie_nxt[11] = wbck_csr_dat[11];//MEIE //这个是个单纯的配置寄存器,只存在cpu指令配置的情况,所以nxt只有cpu指令的写入值
- assign mie_nxt[10:8] = 3'b0;
- assign mie_nxt[ 7] = wbck_csr_dat[ 7];//MTIE
- assign mie_nxt[6:4] = 3'b0;
- assign mie_nxt[ 3] = wbck_csr_dat[ 3];//MSIE
- assign mie_nxt[2:0] = 3'b0;
- sirv_gnrl_dfflr #(`E203_XLEN) mie_dfflr (mie_ena, mie_nxt, mie_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mie = mie_r;
- assign meie_r = csr_mie[11];
- assign mtie_r = csr_mie[ 7];
- assign msie_r = csr_mie[ 3];
- //0x044 URW uip User interrupt pending.
- // We dont support delegation scheme, so no need to support the uip
- //0x344 MRW mip Machine interrupt pending
- wire sel_mip = (csr_idx == 12'h344); // 12'h344地址为mip寄存器,用于指示中断的pending状态
- wire rd_mip = sel_mip & csr_rd_en;
- //wire wr_mip = sel_mip & csr_wr_en;
- // The MxIP is read-only
- wire meip_r;
- wire msip_r;
- wire mtip_r;
- sirv_gnrl_dffr #(1) meip_dffr (ext_irq_r, meip_r, clk, rst_n); // 这三个是mip中的三个有效的bit,只读的 exception interrupt pending
- sirv_gnrl_dffr #(1) msip_dffr (sft_irq_r, msip_r, clk, rst_n); // software interrupt pending
- sirv_gnrl_dffr #(1) mtip_dffr (tmr_irq_r, mtip_r, clk, rst_n); // trap interrupt pending
- wire [`E203_XLEN-1:0] ip_r;
- assign ip_r[31:12] = 20'b0;
- assign ip_r[11] = meip_r;
- assign ip_r[10:8] = 3'b0;
- assign ip_r[ 7] = mtip_r;
- assign ip_r[6:4] = 3'b0;
- assign ip_r[ 3] = msip_r;
- assign ip_r[2:0] = 3'b0;
- wire [`E203_XLEN-1:0] csr_mip = ip_r;
- //
- //0x005 URW utvec User trap handler base address.
- // We dont support user trap, so no utvec needed
- //0x305 MRW mtvec Machine trap-handler base address.
- wire sel_mtvec = (csr_idx == 12'h305); // 12'h305是mtvec寄存器,trap-handler的基地址,就是我们常说的中断向量的基地址
- wire rd_mtvec = csr_rd_en & sel_mtvec;
- `ifdef E203_SUPPORT_MTVEC //{
- wire wr_mtvec = sel_mtvec & csr_wr_en;
- wire mtvec_ena = (wr_mtvec & wbck_csr_wen);
- wire [`E203_XLEN-1:0] mtvec_r;
- wire [`E203_XLEN-1:0] mtvec_nxt = wbck_csr_dat;
- sirv_gnrl_dfflr #(`E203_XLEN) mtvec_dfflr (mtvec_ena, mtvec_nxt, mtvec_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mtvec = mtvec_r;
- `else//}{
- // THe vector table base is a configurable parameter, so we dont support writeable to it
- wire [`E203_XLEN-1:0] csr_mtvec = `E203_MTVEC_TRAP_BASE; // 因为E203这里采用了宏定义的方式设置mtvec,所以直接就不支持软件设置了
- `endif//}
- assign csr_mtvec_r = csr_mtvec;
- //0x340 MRW mscratch
- wire sel_mscratch = (csr_idx == 12'h340); //12'h304是mscratch寄存器,用于在机器模式下快速保存一些配置,用于快速回复现场
- wire rd_mscratch = sel_mscratch & csr_rd_en;
- `ifdef E203_SUPPORT_MSCRATCH //{
- wire wr_mscratch = sel_mscratch & csr_wr_en;
- wire mscratch_ena = (wr_mscratch & wbck_csr_wen);
- wire [`E203_XLEN-1:0] mscratch_r;
- wire [`E203_XLEN-1:0] mscratch_nxt = wbck_csr_dat;
- sirv_gnrl_dfflr #(`E203_XLEN) mscratch_dfflr (mscratch_ena, mscratch_nxt, mscratch_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mscratch = mscratch_r;
- `else//}{
- wire [`E203_XLEN-1:0] csr_mscratch = `E203_XLEN'b0;
- `endif//}
- // 0xB00 MRW mcycle
- // 0xB02 MRW minstret
- // 0xB80 MRW mcycleh
- // 0xB82 MRW minstreth
- wire sel_mcycle = (csr_idx == 12'hB00); //12'hB00 是mcycle寄存器,用于记录处理器执行了多少个时钟周期的64位计数器的低32bit
- wire sel_mcycleh = (csr_idx == 12'hB80); //12'hB80 是mcycleh寄存器 高32bit
- wire sel_minstret = (csr_idx == 12'hB02); //12'hB02 is lower 32bits of instructions-retired counter(记录成功执行了多少指令)
- wire sel_minstreth = (csr_idx == 12'hB82); //12'hB82 is upper 32bits of instructions-retired counter(记录成功执行了多少指令)
- // 0xBFF MRW counterstop 由于上面两个counter都是用于统计cpu性能的,所以当不用统计的时候,给他关掉以节省动态功耗;
- // This register is our self-defined register to stop 因此自定义了一个mcounterstop寄存器用于控制mcycle和minstret的计数开关
- // the cycle/time/instret counters to save dynamic powers
- wire sel_counterstop = (csr_idx == 12'hBFF);// This address is not used by ISA
- // 0xBFE MRW mcgstop
- // This register is our self-defined register to disable the
- // automaticall clock gating for CPU logics for debugging purpose
- wire sel_mcgstop = (csr_idx == 12'hBFE);// This address is not used by ISA 自定义的mcgstop寄存器,用于关闭cpu逻辑的时钟门控???
- // 0xBFD MRW itcmnohold
- // This register is our self-defined register to disble the
- // ITCM SRAM output holdup feature, if set, then we assume
- // ITCM SRAM output cannot holdup last read value
- wire sel_itcmnohold = (csr_idx == 12'hBFD);// This address is not used by ISA 自定义的mitcmnohold,用于配置itcm是否要保持住数据
- // 0xBF0 MRW mdvnob2b
- // This register is our self-defined register to disble the
- // Mul/div back2back feature
- wire sel_mdvnob2b = (csr_idx == 12'hBF0);// This address is not used by ISA 自定义的mdvnob2b 用于配置乘除操作是否开启back2back特性
- wire rd_mcycle = csr_rd_en & sel_mcycle ;
- wire rd_mcycleh = csr_rd_en & sel_mcycleh ;
- wire rd_minstret = csr_rd_en & sel_minstret ;
- wire rd_minstreth = csr_rd_en & sel_minstreth;
- wire rd_itcmnohold = csr_rd_en & sel_itcmnohold;
- wire rd_mdvnob2b = csr_rd_en & sel_mdvnob2b;
- wire rd_counterstop = csr_rd_en & sel_counterstop;
- wire rd_mcgstop = csr_rd_en & sel_mcgstop;
- `ifdef E203_SUPPORT_MCYCLE_MINSTRET //{
- wire wr_mcycle = csr_wr_en & sel_mcycle ;
- wire wr_mcycleh = csr_wr_en & sel_mcycleh ;
- wire wr_minstret = csr_wr_en & sel_minstret ;
- wire wr_minstreth = csr_wr_en & sel_minstreth;
- wire wr_itcmnohold = csr_wr_en & sel_itcmnohold ;
- wire wr_mdvnob2b = csr_wr_en & sel_mdvnob2b ;
- wire wr_counterstop = csr_wr_en & sel_counterstop;
- wire wr_mcgstop = csr_wr_en & sel_mcgstop ;
- wire mcycle_wr_ena = (wr_mcycle & wbck_csr_wen);
- wire mcycleh_wr_ena = (wr_mcycleh & wbck_csr_wen);
- wire minstret_wr_ena = (wr_minstret & wbck_csr_wen);
- wire minstreth_wr_ena = (wr_minstreth & wbck_csr_wen);
- wire itcmnohold_wr_ena = (wr_itcmnohold & wbck_csr_wen);
- wire mdvnob2b_wr_ena = (wr_mdvnob2b & wbck_csr_wen);
- wire counterstop_wr_ena = (wr_counterstop & wbck_csr_wen);
- wire mcgstop_wr_ena = (wr_mcgstop & wbck_csr_wen);
- wire [`E203_XLEN-1:0] mcycle_r ;
- wire [`E203_XLEN-1:0] mcycleh_r ;
- wire [`E203_XLEN-1:0] minstret_r ;
- wire [`E203_XLEN-1:0] minstreth_r;
- wire cy_stop;
- wire ir_stop;
- wire stop_cycle_in_dbg = dbg_stopcycle & dbg_mode; //debug模式下停止时钟模式计数
- wire mcycle_ena = mcycle_wr_ena |
- ((~cy_stop) & (~stop_cycle_in_dbg) & (1'b1)); //如果是cpu写,或者是循序cycle计数的时候,计数寄存器更新使能
- wire mcycleh_ena = mcycleh_wr_ena |
- ((~cy_stop) & (~stop_cycle_in_dbg) & ((mcycle_r == (~(`E203_XLEN'b0))))); //如果是cpu写,计数使能且低32bit计数为全1;
- wire minstret_ena = minstret_wr_ena |
- ((~ir_stop) & (~stop_cycle_in_dbg) & (cmt_instret_ena)); //cpu写,且允许指令计数,且指令被commit了,计数加1
- wire minstreth_ena = minstreth_wr_ena |
- ((~ir_stop) & (~stop_cycle_in_dbg) & ((cmt_instret_ena & (minstret_r == (~(`E203_XLEN'b0))))));//cpu写,且允许指令计数,且指令被commit了,且低32bit为全1,计数加1
- wire [`E203_XLEN-1:0] mcycle_nxt = mcycle_wr_ena ? wbck_csr_dat : (mcycle_r + 1'b1);
- wire [`E203_XLEN-1:0] mcycleh_nxt = mcycleh_wr_ena ? wbck_csr_dat : (mcycleh_r + 1'b1);
- wire [`E203_XLEN-1:0] minstret_nxt = minstret_wr_ena ? wbck_csr_dat : (minstret_r + 1'b1);
- wire [`E203_XLEN-1:0] minstreth_nxt = minstreth_wr_ena ? wbck_csr_dat : (minstreth_r + 1'b1);
- //We need to use the always-on clock for this counter
- sirv_gnrl_dfflr #(`E203_XLEN) mcycle_dfflr (mcycle_ena, mcycle_nxt, mcycle_r , clk_aon, rst_n);
- sirv_gnrl_dfflr #(`E203_XLEN) mcycleh_dfflr (mcycleh_ena, mcycleh_nxt, mcycleh_r , clk_aon, rst_n);
- sirv_gnrl_dfflr #(`E203_XLEN) minstret_dfflr (minstret_ena, minstret_nxt, minstret_r , clk, rst_n);
- sirv_gnrl_dfflr #(`E203_XLEN) minstreth_dfflr (minstreth_ena, minstreth_nxt, minstreth_r, clk, rst_n);
- wire [`E203_XLEN-1:0] counterstop_r;
- wire counterstop_ena = counterstop_wr_ena;
- wire [`E203_XLEN-1:0] counterstop_nxt = {29'b0,wbck_csr_dat[2:0]};// Only LSB 3bits are useful
- sirv_gnrl_dfflr #(`E203_XLEN) counterstop_dfflr (counterstop_ena, counterstop_nxt, counterstop_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mcycle = mcycle_r;
- wire [`E203_XLEN-1:0] csr_mcycleh = mcycleh_r;
- wire [`E203_XLEN-1:0] csr_minstret = minstret_r;
- wire [`E203_XLEN-1:0] csr_minstreth = minstreth_r;
- wire [`E203_XLEN-1:0] csr_counterstop = counterstop_r;
- `else//}{
- wire [`E203_XLEN-1:0] csr_mcycle = `E203_XLEN'b0;
- wire [`E203_XLEN-1:0] csr_mcycleh = `E203_XLEN'b0;
- wire [`E203_XLEN-1:0] csr_minstret = `E203_XLEN'b0;
- wire [`E203_XLEN-1:0] csr_minstreth = `E203_XLEN'b0;
- wire [`E203_XLEN-1:0] csr_counterstop = `E203_XLEN'b0;
- `endif//}
- wire [`E203_XLEN-1:0] itcmnohold_r; // itcmnohold是一个单纯的cpu配置寄存器
- wire itcmnohold_ena = itcmnohold_wr_ena;
- wire [`E203_XLEN-1:0] itcmnohold_nxt = {31'b0,wbck_csr_dat[0]};// Only LSB 1bits are useful
- sirv_gnrl_dfflr #(`E203_XLEN) itcmnohold_dfflr (itcmnohold_ena, itcmnohold_nxt, itcmnohold_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_itcmnohold = itcmnohold_r;
- wire [`E203_XLEN-1:0] mdvnob2b_r; // mdvnob2b也是一个单纯的cpu配置寄存器
- wire mdvnob2b_ena = mdvnob2b_wr_ena;
- wire [`E203_XLEN-1:0] mdvnob2b_nxt = {31'b0,wbck_csr_dat[0]};// Only LSB 1bits are useful
- sirv_gnrl_dfflr #(`E203_XLEN) mdvnob2b_dfflr (mdvnob2b_ena, mdvnob2b_nxt, mdvnob2b_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mdvnob2b = mdvnob2b_r;
- assign cy_stop = counterstop_r[0];// Stop CYCLE counter
- assign tm_stop = counterstop_r[1];// Stop TIME counter
- assign ir_stop = counterstop_r[2];// Stop INSTRET counter
- assign itcm_nohold = itcmnohold_r[0];// ITCM no-hold up feature
- assign mdv_nob2b = mdvnob2b_r[0];// Mul/Div no back2back feature
- wire [`E203_XLEN-1:0] mcgstop_r;// mcgstop 也是一个单纯的cpu配置寄存器
- wire mcgstop_ena = mcgstop_wr_ena;
- wire [`E203_XLEN-1:0] mcgstop_nxt = {30'b0,wbck_csr_dat[1:0]};// Only LSB 2bits are useful
- sirv_gnrl_dfflr #(`E203_XLEN) mcgstop_dfflr (mcgstop_ena, mcgstop_nxt, mcgstop_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mcgstop = mcgstop_r;
- assign core_cgstop = mcgstop_r[0];// Stop Core clock gating
- assign tcm_cgstop = mcgstop_r[1];// Stop TCM clock gating
- //`ifdef E203_SUPPORT_CYCLE //{
- 0xC00 URO cycle
- 0xC80 URO cycleh
- //wire sel_cycle = (csr_idx == 12'hc00);
- //wire sel_cycleh = (csr_idx == 12'hc80);
- //wire rd_cycle = sel_cycle & csr_rd_en;
- //wire wr_cycle = sel_cycle & csr_wr_en;
- //wire cycle_ena = (wr_cycle & wbck_csr_wen);
- //wire rd_cycleh = sel_cycleh & csr_rd_en;
- //wire wr_cycleh = sel_cycleh & csr_wr_en;
- //wire cycleh_ena = (wr_cycleh & wbck_csr_wen);
- //wire [`E203_XLEN-1:0] cycle_r;
- //wire [`E203_XLEN-1:0] cycleh_r;
- //wire [`E203_XLEN-1:0] cycle_nxt = wbck_csr_dat;
- //wire [`E203_XLEN-1:0] cycleh_nxt = wbck_csr_dat;
- //sirv_gnrl_dfflr #(`E203_XLEN) cycle_dfflr (cycle_ena, cycle_nxt, cycle_r, clk, rst_n);
- //sirv_gnrl_dfflr #(`E203_XLEN) cycleh_dfflr(cycleh_ena,cycleh_nxt,cycleh_r,clk, rst_n);
- //wire [`E203_XLEN-1:0] csr_cycle = cycle_r;
- //wire [`E203_XLEN-1:0] csr_cycleh = cycleh_r;
- //`else//}{
- //wire [`E203_XLEN-1:0] csr_cycle = `E203_XLEN'b0;
- //wire [`E203_XLEN-1:0] csr_cycleh = `E203_XLEN'b0;
- //`endif//}
- //
- //0x041 URW uepc User exception program counter.
- // We dont support user trap, so no uepc needed
- //0x341 MRW mepc Machine exception program counter.
- wire sel_mepc = (csr_idx == 12'h341); // mepc 是异常模式下的pc指针
- wire rd_mepc = sel_mepc & csr_rd_en;
- wire wr_mepc = sel_mepc & csr_wr_en;
- wire epc_ena = (wr_mepc & wbck_csr_wen) | cmt_epc_ena;
- wire [`E203_PC_SIZE-1:0] epc_r;
- wire [`E203_PC_SIZE-1:0] epc_nxt;
- 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];
- assign epc_nxt[0] = 1'b0;// Must not hold PC which will generate the misalign exception according to ISA
- sirv_gnrl_dfflr #(`E203_PC_SIZE) epc_dfflr (epc_ena, epc_nxt, epc_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mepc;
- wire dummy_0;
- assign {dummy_0,csr_mepc} = {{`E203_XLEN+1-`E203_PC_SIZE{1'b0}},epc_r};
- assign csr_epc_r = csr_mepc;
- //0x042 URW ucause User trap cause.
- // We dont support user trap, so no ucause needed
- //0x342 MRW mcause Machine trap cause.
- wire sel_mcause = (csr_idx == 12'h342); //12'h342 mcause 用于保存进入异常之前出错的原因,以便与对异常原因进行诊断和调试
- wire rd_mcause = sel_mcause & csr_rd_en;
- wire wr_mcause = sel_mcause & csr_wr_en;
- wire cause_ena = (wr_mcause & wbck_csr_wen) | cmt_cause_ena; // 如果cpu写,或者指令commit的时候需要记录cause
- wire [`E203_XLEN-1:0] cause_r;
- wire [`E203_XLEN-1:0] cause_nxt;
- assign cause_nxt[31] = cmt_cause_ena ? cmt_cause[31] : wbck_csr_dat[31];
- assign cause_nxt[30:4] = 27'b0;
- assign cause_nxt[3:0] = cmt_cause_ena ? cmt_cause[3:0] : wbck_csr_dat[3:0];
- sirv_gnrl_dfflr #(`E203_XLEN) cause_dfflr (cause_ena, cause_nxt, cause_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mcause = cause_r;
- //0x043 URW ubadaddr User bad address.
- // We dont support user trap, so no ubadaddr needed
- //0x343 MRW mbadaddr Machine bad address.
- wire sel_mbadaddr = (csr_idx == 12'h343);
- wire rd_mbadaddr = sel_mbadaddr & csr_rd_en; // 用于记录有问题的指令的地址,跟上面的寄存器一样,要么是cpu主动写入,要么是commit指令的时候写入
- wire wr_mbadaddr = sel_mbadaddr & csr_wr_en;
- wire cmt_trap_badaddr_ena = cmt_badaddr_ena;
- wire badaddr_ena = (wr_mbadaddr & wbck_csr_wen) | cmt_trap_badaddr_ena;
- wire [`E203_ADDR_SIZE-1:0] badaddr_r;
- wire [`E203_ADDR_SIZE-1:0] badaddr_nxt;
- assign badaddr_nxt = cmt_trap_badaddr_ena ? cmt_badaddr : wbck_csr_dat[`E203_ADDR_SIZE-1:0];
- sirv_gnrl_dfflr #(`E203_ADDR_SIZE) badaddr_dfflr (badaddr_ena, badaddr_nxt, badaddr_r, clk, rst_n);
- wire [`E203_XLEN-1:0] csr_mbadaddr;
- wire dummy_1;
- assign {dummy_1,csr_mbadaddr} = {{`E203_XLEN+1-`E203_ADDR_SIZE{1'b0}},badaddr_r};
- // We dont support the delegation scheme, so no need to implement
- // delegete registers
- //0x301 MRW misa ISA and extensions
- wire sel_misa = (csr_idx == 12'h301); // 12'h301 misa寄存器,只读的寄存器,用于指示当前寄存器所支持的架构特性
- wire rd_misa = sel_misa & csr_rd_en;
- // Only implemented the M mode, IMC or EMC
- wire [`E203_XLEN-1:0] csr_misa = {
- 2'b1
- ,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'b1 // 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
- `ifdef E203_RFREG_NUM_IS_32
- ,1'b1 // 8 I RV32I/64I/128I base ISA
- `else
- ,1'b0
- `endif
- ,1'b0 // 7 H Hypervisor mode implemented
- ,1'b0 // 6 G Additional standard extensions present
- `ifndef E203_HAS_FPU//{
- ,1'b0 // 5 F Single-precision floating-point extension
- `endif//
- `ifdef E203_RFREG_NUM_IS_32
- ,1'b0 // 4 E RV32E base ISA
- `else
- ,1'b1 //
- `endif
- `ifndef E203_HAS_FPU//{
- ,1'b0 // 3 D Double-precision floating-point extension
- `endif//
- ,1'b1 // 2 C Compressed extension
- ,1'b0 // 1 B Tentatively reserved for Bit operations extension
- `ifdef E203_SUPPORT_AMO//{
- ,1'b1 // 0 A Atomic extension
- `endif//E203_SUPPORT_AMO}
- `ifndef E203_SUPPORT_AMO//{
- ,1'b0 // 0 A Atomic extension
- `endif//}
- };
- //Machine Information Registers
- //0xF11 MRO mvendorid Vendor ID.
- //0xF12 MRO marchid Architecture ID.
- //0xF13 MRO mimpid Implementation ID.
- //0xF14 MRO mhartid Hardware thread ID.
- wire [`E203_XLEN-1:0] csr_mvendorid = `E203_XLEN'h`E203_MVENDORID; // vendor ID 寄存器
- wire [`E203_XLEN-1:0] csr_marchid = `E203_XLEN'h`E203_MARCHID ; // 架构 Id 寄存器
- wire [`E203_XLEN-1:0] csr_mimpid = `E203_XLEN'h`E203_MIMPID ; // 处理器核的硬件实现编号ID 寄存器
- wire [`E203_XLEN-1:0] csr_mhartid = {{`E203_XLEN-`E203_HART_ID_W{1'b0}},core_mhartid}; // 处理器Hart ID
- wire rd_mvendorid = csr_rd_en & (csr_idx == 12'hF11);
- wire rd_marchid = csr_rd_en & (csr_idx == 12'hF12);
- wire rd_mimpid = csr_rd_en & (csr_idx == 12'hF13);
- wire rd_mhartid = csr_rd_en & (csr_idx == 12'hF14);
- //0x7b0 Debug Control and Status
- //0x7b1 Debug PC
- //0x7b2 Debug Scratch Register
- //0x7a0 Trigger selection register
- wire sel_dcsr = (csr_idx == 12'h7b0); // debug 模式下的csr( Control and status register)
- wire sel_dpc = (csr_idx == 12'h7b1); // debug 模式下的PC指针
- wire sel_dscratch = (csr_idx == 12'h7b2); // debug 模式下的scratch寄存器,用于临时保存数据,便于恢复现场
- wire rd_dcsr = dbg_mode & csr_rd_en & sel_dcsr ;
- wire rd_dpc = dbg_mode & csr_rd_en & sel_dpc ;
- wire rd_dscratch = dbg_mode & csr_rd_en & sel_dscratch;
- assign wr_dcsr_ena = dbg_mode & csr_wr_en & sel_dcsr ;
- assign wr_dpc_ena = dbg_mode & csr_wr_en & sel_dpc ;
- assign wr_dscratch_ena = dbg_mode & csr_wr_en & sel_dscratch;
- assign wr_csr_nxt = wbck_csr_dat;
- wire [`E203_XLEN-1:0] csr_dcsr = dcsr_r ;
- `ifdef E203_PC_SIZE_IS_16
- wire [`E203_XLEN-1:0] csr_dpc = {{`E203_XLEN-`E203_PC_SIZE{1'b0}},dpc_r};
- `endif
- `ifdef E203_PC_SIZE_IS_24
- wire [`E203_XLEN-1:0] csr_dpc = {{`E203_XLEN-`E203_PC_SIZE{1'b0}},dpc_r};
- `endif
- `ifdef E203_PC_SIZE_IS_32
- wire [`E203_XLEN-1:0] csr_dpc = dpc_r ;
- `endif
- wire [`E203_XLEN-1:0] csr_dscratch = dscratch_r;
- assign csr_dpc_r = dpc_r;
- /
- // Generate the Read path
- //Currently we only support the M mode to simplify the implementation and
- // reduce the gatecount because we are a privite core
- assign u_mode = 1'b0; // 当前的cpu所处的模式
- assign s_mode = 1'b0;
- assign h_mode = 1'b0;
- assign m_mode = 1'b1;
- assign read_csr_dat = `E203_XLEN'b0 // csr寄存器的读通路
- //| ({`E203_XLEN{rd_ustatus }} & csr_ustatus )
- | ({`E203_XLEN{rd_mstatus }} & csr_mstatus )
- | ({`E203_XLEN{rd_mie }} & csr_mie )
- | ({`E203_XLEN{rd_mtvec }} & csr_mtvec )
- | ({`E203_XLEN{rd_mepc }} & csr_mepc )
- | ({`E203_XLEN{rd_mscratch }} & csr_mscratch )
- | ({`E203_XLEN{rd_mcause }} & csr_mcause )
- | ({`E203_XLEN{rd_mbadaddr }} & csr_mbadaddr )
- | ({`E203_XLEN{rd_mip }} & csr_mip )
- | ({`E203_XLEN{rd_misa }} & csr_misa )
- | ({`E203_XLEN{rd_mvendorid}} & csr_mvendorid)
- | ({`E203_XLEN{rd_marchid }} & csr_marchid )
- | ({`E203_XLEN{rd_mimpid }} & csr_mimpid )
- | ({`E203_XLEN{rd_mhartid }} & csr_mhartid )
- | ({`E203_XLEN{rd_mcycle }} & csr_mcycle )
- | ({`E203_XLEN{rd_mcycleh }} & csr_mcycleh )
- | ({`E203_XLEN{rd_minstret }} & csr_minstret )
- | ({`E203_XLEN{rd_minstreth}} & csr_minstreth)
- | ({`E203_XLEN{rd_counterstop}} & csr_counterstop)// Self-defined
- | ({`E203_XLEN{rd_mcgstop}} & csr_mcgstop)// Self-defined
- | ({`E203_XLEN{rd_itcmnohold}} & csr_itcmnohold)// Self-defined
- | ({`E203_XLEN{rd_mdvnob2b}} & csr_mdvnob2b)// Self-defined
- | ({`E203_XLEN{rd_dcsr }} & csr_dcsr )
- | ({`E203_XLEN{rd_dpc }} & csr_dpc )
- | ({`E203_XLEN{rd_dscratch }} & csr_dscratch)
- ;
复制代码
本篇完,感谢关注:RISC-V单片机中文网 |
上一篇: CKB-VM:连接硬件和软件的桥梁——Nervos@RISC-V Roadshow下一篇: RISC-V处理器:1.取指令 RTL 代码分析
|