E203 蜂鸟 RISC-V处理器代码阅读笔记 之指令译码模块 e203_exu_decode.v

这个文章记录了我学习RISC-V蜂鸟E203处理器的学习历程
这是我正式阅读代码学习的第1个源代码文件

针对代码的学习,我结合自己的理解对每个module的接口,以及内部关键信号做了详细的注释说明
原创不易,请保护版权,转载联系作者,并请注明出处,标出原始链接谢谢~~
e203_exu_decode.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 decode module to decode the instruction details
//
// ====================================================================
// =========  我自己的注释: 
//    exu根据指令的指示执行相应的动作,指令可以理解成编排好的二进制数,exu在执行前需要将
// 组成指令的这些二进制数解释成各个便于exu识别的信号,也就是所谓的指令译码
// 译码逻辑是纯组合逻辑,没有时序概念在里面;但是i_instr和in_pc等输入是按时序送进来,指令结果的输出也是由exu按时序去取
// =========`include "e203_defines.v"module e203_exu_decode(//// The IR stage to Decoderinput  [`E203_INSTR_SIZE-1:0] i_instr, //取指逻辑取回的指令,作为输入等待译码input  [`E203_PC_SIZE-1:0] i_pc,       //取值逻辑取回的指令的地址,也就是说取回的这条指令的PC值input  i_prdt_taken, input  i_misalgn,              // The fetch misalign   输入的指令总线送过来的信号input  i_buserr,               // The fetch bus error  输入的指令总线的错误信号input  i_muldiv_b2b,           // The back2back case for mul/div  input  dbg_mode,               // 指示当前CPU是否处于dbg模式//// The Decoded Info-Bus  下面输出译码结果output dec_rs1x0, //指令的源操作数rs1为X0的指示output dec_rs2x0, //指令的源操作数rs2为X0的指示output dec_rs1en, //指令是否需要操作rs1寄存器output dec_rs2en, //指令是否需要操作rs2寄存器output dec_rdwen, //指令是否需要操作rd寄存器output [`E203_RFIDX_WIDTH-1:0] dec_rs1idx, //源操作数rs1的cpu内部地址output [`E203_RFIDX_WIDTH-1:0] dec_rs2idx, //源操作数rs2的cpu内部地址output [`E203_RFIDX_WIDTH-1:0] dec_rdidx,  //目的操作数rd的cpu内部地址output [`E203_DECINFO_WIDTH-1:0] dec_info, //解码出的指令信息,用于表示指令具体是啥指令,做啥操作的 output [`E203_XLEN-1:0] dec_imm,           //译码出指令中的立即数output [`E203_PC_SIZE-1:0] dec_pc,         //译码的指令的PC值output dec_misalgn,  //直接根据i_misalgn生成的,如果总线送过来就是misalgn,那么指令就是misalignoutput dec_buserr,   //根据i_buserr直接生成的output dec_ilegl,    //解析出的指令不合法标记,就是说指令中有些位段是有要求的,比如说立即数中某一bit必须为0,如果不是0,那么就输出不合法等等output dec_mulhsu, // mul-high-signed-unsigned rs1有符号,rs2无符号,相乘结果(64bit)的高32bit放入rdoutput dec_mul   , // mul rs1无符号,rs2无符号,(有符号无符号其实是一样的)相乘结果(64bit)的低32bit放入rdoutput dec_div   , // div rs1有符号,rs2有符号output dec_rem   , // 取  rs1有符号与rs2有符号数,取余数送到dr;output dec_divu  , // 无符号取商送droutput dec_remu  , // 无符号取余送droutput dec_rv32,  //表示当前指令是rsic-v32位指令,还是16位指令output dec_bjp,   //表示当前指令是普通指令还是分支跳转指令,表示是否属于bxx指令或jxx指令的一种output dec_jal,   //属于jal指令output dec_jalr,  //数据jalr指令output dec_bxx,   //属于BXX指令,(BEQ,BNE等带条件分支指令)output [`E203_RFIDX_WIDTH-1:0] dec_jalr_rs1idx,   //针对jalr指令,其首先要取出rs1操作数,然后与立即数相加才能得到值+4作为新的pc,为了取rs1,指令里带了rs1的地址(cpu内部index)output [`E203_XLEN-1:0] dec_bjp_imm               //针对bxx指令,如果条件满足的话,会把12bit立即数(有符号)×2然后与pc相加,作为新的pc;这里是译码出的指令的立即数 );wire [32-1:0] rv32_instr = i_instr;wire [16-1:0] rv16_instr = i_instr[15:0];wire [6:0]  opcode = rv32_instr[6:0]; //指令的低7bit为指令的操作码,指示了指令具体是哪一条指令,是做什么操作的wire opcode_1_0_00  = (opcode[1:0] == 2'b00);  // 这里判断操作码的低两位,低两位如果为11的话,说明不是16位指令,否则就是16位指令wire opcode_1_0_01  = (opcode[1:0] == 2'b01);wire opcode_1_0_10  = (opcode[1:0] == 2'b10);wire opcode_1_0_11  = (opcode[1:0] == 2'b11);wire rv32 = (~(i_instr[4:2] == 3'b111)) & opcode_1_0_11; //指令的[1:0]bit为2'b111,[4:2]bit != 3'b111;那么指令为32位指令wire [4:0]  rv32_rd     = rv32_instr[11:7];    //指令编码中[11:7]是指令的目的操作数rd的cpu内部地址索引wire [2:0]  rv32_func3  = rv32_instr[14:12];   //编码指令功能的区域wire [4:0]  rv32_rs1    = rv32_instr[19:15];   //指令的源操作数rs1的cpu内部地址索引wire [4:0]  rv32_rs2    = rv32_instr[24:20];   //指令的源操作数rs2的cpu内部地址索引wire [6:0]  rv32_func7  = rv32_instr[31:25];   //编码指令功能的区域wire [4:0]  rv16_rd     = rv32_rd;wire [4:0]  rv16_rs1    = rv16_rd; //16位指令源操作数和目的操作数在同一个位置,关于指令的具体字段含义可以查看书最后的附录F wire [4:0]  rv16_rs2    = rv32_instr[6:2];wire [4:0]  rv16_rdd    = {2'b01,rv32_instr[4:2]};wire [4:0]  rv16_rss1   = {2'b01,rv32_instr[9:7]};wire [4:0]  rv16_rss2   = rv16_rdd;wire [2:0]  rv16_func3  = rv32_instr[15:13];// We generate the signals and reused them as much as possible to save gatecountswire opcode_4_2_000 = (opcode[4:2] == 3'b000);wire opcode_4_2_001 = (opcode[4:2] == 3'b001);wire opcode_4_2_010 = (opcode[4:2] == 3'b010);wire opcode_4_2_011 = (opcode[4:2] == 3'b011);wire opcode_4_2_100 = (opcode[4:2] == 3'b100);wire opcode_4_2_101 = (opcode[4:2] == 3'b101);wire opcode_4_2_110 = (opcode[4:2] == 3'b110);wire opcode_4_2_111 = (opcode[4:2] == 3'b111);wire opcode_6_5_00  = (opcode[6:5] == 2'b00);wire opcode_6_5_01  = (opcode[6:5] == 2'b01);wire opcode_6_5_10  = (opcode[6:5] == 2'b10);wire opcode_6_5_11  = (opcode[6:5] == 2'b11);wire rv32_func3_000 = (rv32_func3 == 3'b000);wire rv32_func3_001 = (rv32_func3 == 3'b001);wire rv32_func3_010 = (rv32_func3 == 3'b010);wire rv32_func3_011 = (rv32_func3 == 3'b011);wire rv32_func3_100 = (rv32_func3 == 3'b100);wire rv32_func3_101 = (rv32_func3 == 3'b101);wire rv32_func3_110 = (rv32_func3 == 3'b110);wire rv32_func3_111 = (rv32_func3 == 3'b111);wire rv16_func3_000 = (rv16_func3 == 3'b000);wire rv16_func3_001 = (rv16_func3 == 3'b001);wire rv16_func3_010 = (rv16_func3 == 3'b010);wire rv16_func3_011 = (rv16_func3 == 3'b011);wire rv16_func3_100 = (rv16_func3 == 3'b100);wire rv16_func3_101 = (rv16_func3 == 3'b101);wire rv16_func3_110 = (rv16_func3 == 3'b110);wire rv16_func3_111 = (rv16_func3 == 3'b111);wire rv32_func7_0000000 = (rv32_func7 == 7'b0000000);wire rv32_func7_0100000 = (rv32_func7 == 7'b0100000);wire rv32_func7_0000001 = (rv32_func7 == 7'b0000001);wire rv32_func7_0000101 = (rv32_func7 == 7'b0000101);wire rv32_func7_0001001 = (rv32_func7 == 7'b0001001);wire rv32_func7_0001101 = (rv32_func7 == 7'b0001101);wire rv32_func7_0010101 = (rv32_func7 == 7'b0010101);wire rv32_func7_0100001 = (rv32_func7 == 7'b0100001);wire rv32_func7_0010001 = (rv32_func7 == 7'b0010001);wire rv32_func7_0101101 = (rv32_func7 == 7'b0101101);wire rv32_func7_1111111 = (rv32_func7 == 7'b1111111);wire rv32_func7_0000100 = (rv32_func7 == 7'b0000100); wire rv32_func7_0001000 = (rv32_func7 == 7'b0001000); wire rv32_func7_0001100 = (rv32_func7 == 7'b0001100); wire rv32_func7_0101100 = (rv32_func7 == 7'b0101100); wire rv32_func7_0010000 = (rv32_func7 == 7'b0010000); wire rv32_func7_0010100 = (rv32_func7 == 7'b0010100); wire rv32_func7_1100000 = (rv32_func7 == 7'b1100000); wire rv32_func7_1110000 = (rv32_func7 == 7'b1110000); wire rv32_func7_1010000 = (rv32_func7 == 7'b1010000); wire rv32_func7_1101000 = (rv32_func7 == 7'b1101000); wire rv32_func7_1111000 = (rv32_func7 == 7'b1111000); wire rv32_func7_1010001 = (rv32_func7 == 7'b1010001);  wire rv32_func7_1110001 = (rv32_func7 == 7'b1110001);  wire rv32_func7_1100001 = (rv32_func7 == 7'b1100001);  wire rv32_func7_1101001 = (rv32_func7 == 7'b1101001);  wire rv32_rs1_x0 = (rv32_rs1 == 5'b00000); // rs1源操作数是X0wire rv32_rs2_x0 = (rv32_rs2 == 5'b00000); // rs2源操作数是X0wire rv32_rs2_x1 = (rv32_rs2 == 5'b00001); wire rv32_rd_x0  = (rv32_rd  == 5'b00000);wire rv32_rd_x2  = (rv32_rd  == 5'b00010);wire rv16_rs1_x0 = (rv16_rs1 == 5'b00000);wire rv16_rs2_x0 = (rv16_rs2 == 5'b00000);wire rv16_rd_x0  = (rv16_rd  == 5'b00000);wire rv16_rd_x2  = (rv16_rd  == 5'b00010);wire rv32_rs1_x31 = (rv32_rs1 == 5'b11111);wire rv32_rs2_x31 = (rv32_rs2 == 5'b11111);wire rv32_rd_x31  = (rv32_rd  == 5'b11111);wire rv32_load     = opcode_6_5_00 & opcode_4_2_000 & opcode_1_0_11; wire rv32_store    = opcode_6_5_01 & opcode_4_2_000 & opcode_1_0_11; wire rv32_madd     = opcode_6_5_10 & opcode_4_2_000 & opcode_1_0_11; wire rv32_branch   = opcode_6_5_11 & opcode_4_2_000 & opcode_1_0_11; wire rv32_load_fp  = opcode_6_5_00 & opcode_4_2_001 & opcode_1_0_11;  // FLW wire rv32_store_fp = opcode_6_5_01 & opcode_4_2_001 & opcode_1_0_11; wire rv32_msub     = opcode_6_5_10 & opcode_4_2_001 & opcode_1_0_11; wire rv32_jalr     = opcode_6_5_11 & opcode_4_2_001 & opcode_1_0_11; wire rv32_custom0  = opcode_6_5_00 & opcode_4_2_010 & opcode_1_0_11; wire rv32_custom1  = opcode_6_5_01 & opcode_4_2_010 & opcode_1_0_11; wire rv32_nmsub    = opcode_6_5_10 & opcode_4_2_010 & opcode_1_0_11; wire rv32_resved0  = opcode_6_5_11 & opcode_4_2_010 & opcode_1_0_11; wire rv32_miscmem  = opcode_6_5_00 & opcode_4_2_011 & opcode_1_0_11;  //00_011_11  FENCE `ifdef E203_SUPPORT_AMO//{wire rv32_amo      = opcode_6_5_01 & opcode_4_2_011 & opcode_1_0_11;  //`endif//E203_SUPPORT_AMO}`ifndef E203_SUPPORT_AMO//{wire rv32_amo      = 1'b0;`endif//}wire rv32_nmadd    = opcode_6_5_10 & opcode_4_2_011 & opcode_1_0_11; wire rv32_jal      = opcode_6_5_11 & opcode_4_2_011 & opcode_1_0_11; wire rv32_op_imm   = opcode_6_5_00 & opcode_4_2_100 & opcode_1_0_11; wire rv32_op       = opcode_6_5_01 & opcode_4_2_100 & opcode_1_0_11; wire rv32_op_fp    = opcode_6_5_10 & opcode_4_2_100 & opcode_1_0_11; wire rv32_system   = opcode_6_5_11 & opcode_4_2_100 & opcode_1_0_11;


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部