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

E203 译码模块(1)

[复制链接]

  离线 

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

    [LV.3]

    发表于 2021-3-6 15:18:23 | 显示全部楼层 |阅读模式

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

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

    x
    本帖最后由 皋陶 于 2021-3-6 15:25 编辑


    E203是两级流水线结构,第一级是IFU进行取指操作,第二级包括译码、执行、交付和写回等功能。架构图如下:
    国内芯片技术交流-E203 译码模块(1)risc-v单片机中文社区(1)
         译码模块就是把机器码翻译成对应的输出功能。E203支持RV32IMAC,它的译码器模块是纯的组合电路实现,相对比较简单。只要熟悉了RiscV的指令规范,很容易看懂。

         译码模块的输入信号来自于IFU模块,包括以下信号:
    1. input  [`E203_INSTR_SIZE-1:0] i_instr, //来自IFU的32位指令
    2. input  [`E203_PC_SIZE-1:0] i_pc,       //来自IFU的当前指令PC
    3. input  i_prdt_taken,           //预测需要跳转,来自IFU模块的分支预测单元,对分支跳转指令有用,如果当前指令为分支跳转指令,该信号会被传递到相应的info_bus
    4. input  i_misalgn,              // 表示当前指令遇到了分支跳转异常
    5. input  i_buserr,               // 表面当前指令遭遇了取指存储器访问错误
    6. input  i_muldiv_b2b,           // 前后临接的mul和div指令时置1,如果当前指令为乘法除法指令,该信号传递到相应的info_bus

    7. input  dbg_mode,   //debug模式下,忽视dret指令异常的情况
    复制代码
    译码模块的输出包括以下信号:
    1. output dec_rs1x0, // 该指令源操作数1为x0
    2. output dec_rs2x0, // 该指令源操作数2为x0
    3. output dec_rs1en, //该指令需要读取源操作数1
    4. output dec_rs2en, //该指令需要读取源操作数2
    5. output dec_rdwen, //该指令需要写结果操作数到目的寄存器
    6. output [`E203_RFIDX_WIDTH-1:0] dec_rs1idx,  //源操作数1的寄存器索引
    7. output [`E203_RFIDX_WIDTH-1:0] dec_rs2idx, //源操作数2的寄存器索引
    8. output [`E203_RFIDX_WIDTH-1:0] dec_rdidx,  //目的寄存器索引
    9. output [`E203_DECINFO_WIDTH-1:0] dec_info, //该指令的其它信息,被打包成一组宽信号,称之为信息总线(info bus).
    10. output [`E203_XLEN-1:0] dec_imm, //该指令使用的立即数值。
    11. output [`E203_PC_SIZE-1:0] dec_pc, // 该指令的pc值,等于输入的i_pc
    12. output dec_misalgn, //指令遇到了分支跳转异常,等于输入的misalgn
    13. output dec_buserr,  //指令遭遇了取指存储器访问错误,等于输入的i_buserr
    14. output dec_ilegl, //解码后,发现该指令是非法指令


    15. output dec_mulhsu, //指令为 mulh或mulhsu或mulhu,这些乘法指令都把结果的高32位放到目的寄存器
    16. output dec_mul   , //指令为乘法指令
    17. output dec_div   , //指令为除法指令
    18. output dec_rem   ,//指数为取余数指令
    19. output dec_divu  ,//指令为无符号数除法指令
    20. output dec_remu  ,//指令为无符号数取余数指令

    21. output dec_rv32, //该指令为32位指令,为0的话则是16位的压缩指令
    22. output dec_bjp, //该指令为跳转指令,jal 或者jalr或者bxx指令
    23. output dec_jal,  //该指令为jal指令
    24. output dec_jalr, //该指令为jalr指令
    25. output dec_bxx, //该指令为bxx

    26. output [`E203_RFIDX_WIDTH-1:0] dec_jalr_rs1idx, //jalr指令中rs1寄存器索引
    27. output [`E203_XLEN-1:0] dec_bjp_imm  //bjp指令中的立即数
    复制代码
    下面代码判断指令是32位指令还是16位指令的代码。操作码的低2位11,且3到5位不为111,则为rv32指令,否则为16位指令,因为E203不支持rv64,所以用一位信号就可以表示rv32和rvc了。
    1. wire [32-1:0] rv32_instr = i_instr;
    2. wire [16-1:0] rv16_instr = i_instr[15:0];
    3. //指令的低7位为操作码
    4. wire [6:0]  opcode = rv32_instr[6:0];

    5. wire opcode_1_0_00  = (opcode[1:0] == 2'b00);
    6. wire opcode_1_0_01  = (opcode[1:0] == 2'b01);
    7. wire opcode_1_0_10  = (opcode[1:0] == 2'b10);
    8. wire opcode_1_0_11  = (opcode[1:0] == 2'b11);
    9. //为32位指令或者16位指令
    10. wire rv32 = (~(i_instr[4:2] == 3'b111)) & opcode_1_0_11;
    复制代码
    下面代码为取出32位指令和16位指令的关键编码段。RVC的编码比较复杂,有些指令寄存器为3位表示,有些为5位表示,立即数通常都有旋转,旋转格式还很多。具体参见 RV32C指令集
    1. wire [4:0]  rv32_rd     = rv32_instr[11:7]; // 目的寄存器索引
    2. wire [2:0]  rv32_func3  = rv32_instr[14:12];//func3段
    3. wire [4:0]  rv32_rs1    = rv32_instr[19:15];//源操作数1寄存器索引
    4. wire [4:0]  rv32_rs2    = rv32_instr[24:20];//源操作数2寄存器索引
    5. wire [6:0]  rv32_func7  = rv32_instr[31:25];//func7段
    6. //CR  15-12 func4, 11-7 rd/rs1, 6-2 rs2, 0-1 opcode
    7. //CI  15-13 func3, 12 imm,11-7 rd/rs1,6-2 imm, 0-1 opcode
    8. wire [4:0]  rv16_rd     = rv32_rd;
    9. wire [4:0]  rv16_rs1    = rv16_rd;
    10. wire [4:0]  rv16_rs2    = rv32_instr[6:2];
    11. //CIW,CL,CS,CA,CB,CJ
    12. //rdd=rd', rss1=rs1', rss2=rs2' short register, x8-x15, f8-f15
    13. wire [4:0]  rv16_rdd    = {2'b01,rv32_instr[4:2]};
    14. wire [4:0]  rv16_rss1   = {2'b01,rv32_instr[9:7]};
    15. wire [4:0]  rv16_rss2   = rv16_rdd;

    16. wire [2:0]  rv16_func3  = rv32_instr[15:13]
    复制代码
    下面的代码产生指令中的关键信息判断,用于后面的代码复用。
    1. // We generate the signals and reused them as much as possible to save gatecounts
    2.   wire opcode_4_2_000 = (opcode[4:2] == 3'b000);
    3.   wire opcode_4_2_001 = (opcode[4:2] == 3'b001);
    4.    wire opcode_4_2_010 = (opcode[4:2] == 3'b010);
    5.    wire opcode_4_2_011 = (opcode[4:2] == 3'b011);
    6.    wire opcode_4_2_100 = (opcode[4:2] == 3'b100);
    7.    wire opcode_4_2_101 = (opcode[4:2] == 3'b101);
    8.    wire opcode_4_2_110 = (opcode[4:2] == 3'b110);
    9.    wire opcode_4_2_111 = (opcode[4:2] == 3'b111);
    10.    wire opcode_6_5_00  = (opcode[6:5] == 2'b00);
    11.    wire opcode_6_5_01  = (opcode[6:5] == 2'b01);
    12.    wire opcode_6_5_10  = (opcode[6:5] == 2'b10);
    13.    wire opcode_6_5_11  = (opcode[6:5] == 2'b11);

    14.   wire rv32_func3_000 = (rv32_func3 == 3'b000);
    15.    wire rv32_func3_001 = (rv32_func3 == 3'b001);
    16.    wire rv32_func3_010 = (rv32_func3 == 3'b010);
    17.    wire rv32_func3_011 = (rv32_func3 == 3'b011);
    18.    wire rv32_func3_100 = (rv32_func3 == 3'b100);
    19.    wire rv32_func3_101 = (rv32_func3 == 3'b101);
    20.    wire rv32_func3_110 = (rv32_func3 == 3'b110);
    21.    wire rv32_func3_111 = (rv32_func3 == 3'b111);

    22.   wire rv16_func3_000 = (rv16_func3 == 3'b000);
    23.    wire rv16_func3_001 = (rv16_func3 == 3'b001);
    24.    wire rv16_func3_010 = (rv16_func3 == 3'b010);
    25.    wire rv16_func3_011 = (rv16_func3 == 3'b011);
    26.    wire rv16_func3_100 = (rv16_func3 == 3'b100);
    27.    wire rv16_func3_101 = (rv16_func3 == 3'b101);
    28.    wire rv16_func3_110 = (rv16_func3 == 3'b110);
    29.    wire rv16_func3_111 = (rv16_func3 == 3'b111);

    30.   wire rv32_func7_0000000 = (rv32_func7 == 7'b0000000);
    31.    wire rv32_func7_0100000 = (rv32_func7 == 7'b0100000);
    32.    wire rv32_func7_0000001 = (rv32_func7 == 7'b0000001);
    33.    wire rv32_func7_0000101 = (rv32_func7 == 7'b0000101);
    34.    wire rv32_func7_0001001 = (rv32_func7 == 7'b0001001);
    35.    wire rv32_func7_0001101 = (rv32_func7 == 7'b0001101);
    36.    wire rv32_func7_0010101 = (rv32_func7 == 7'b0010101);
    37.    wire rv32_func7_0100001 = (rv32_func7 == 7'b0100001);
    38.    wire rv32_func7_0010001 = (rv32_func7 == 7'b0010001);
    39.    wire rv32_func7_0101101 = (rv32_func7 == 7'b0101101);
    40.    wire rv32_func7_1111111 = (rv32_func7 == 7'b1111111);
    41.    wire rv32_func7_0000100 = (rv32_func7 == 7'b0000100);
    42.    wire rv32_func7_0001000 = (rv32_func7 == 7'b0001000);
    43.    wire rv32_func7_0001100 = (rv32_func7 == 7'b0001100);
    44.    wire rv32_func7_0101100 = (rv32_func7 == 7'b0101100);
    45.    wire rv32_func7_0010000 = (rv32_func7 == 7'b0010000);
    46.    wire rv32_func7_0010100 = (rv32_func7 == 7'b0010100);
    47.    wire rv32_func7_1100000 = (rv32_func7 == 7'b1100000);
    48.    wire rv32_func7_1110000 = (rv32_func7 == 7'b1110000);
    49.    wire rv32_func7_1010000 = (rv32_func7 == 7'b1010000);
    50.    wire rv32_func7_1101000 = (rv32_func7 == 7'b1101000);
    51.    wire rv32_func7_1111000 = (rv32_func7 == 7'b1111000);
    52.    wire rv32_func7_1010001 = (rv32_func7 == 7'b1010001);
    53.    wire rv32_func7_1110001 = (rv32_func7 == 7'b1110001);
    54.    wire rv32_func7_1100001 = (rv32_func7 == 7'b1100001);
    55.    wire rv32_func7_1101001 = (rv32_func7 == 7'b1101001);

    56.   wire rv32_rs1_x0 = (rv32_rs1 == 5'b00000);
    57.    wire rv32_rs2_x0 = (rv32_rs2 == 5'b00000);
    58.    wire rv32_rs2_x1 = (rv32_rs2 == 5'b00001);
    59.    wire rv32_rd_x0  = (rv32_rd  == 5'b00000);
    60.    wire rv32_rd_x2  = (rv32_rd  == 5'b00010);

    61.   wire rv16_rs1_x0 = (rv16_rs1 == 5'b00000);
    62.    wire rv16_rs2_x0 = (rv16_rs2 == 5'b00000);
    63.    wire rv16_rd_x0  = (rv16_rd  == 5'b00000);
    64.    wire rv16_rd_x2  = (rv16_rd  == 5'b00010);

    65.   wire rv32_rs1_x31 = (rv32_rs1 == 5'b11111);
    66.    wire rv32_rs2_x31 = (rv32_rs2 == 5'b11111);
    67.    wire rv32_rd_x31  = (rv32_rd  == 5'b11111);
    复制代码

    对32位指令和16位指令进行译码
    1. //rv32 load指令,opcode是0000011,不同load指令通过func3区分
    2. wire rv32_load     = opcode_6_5_00 & opcode_4_2_000 & opcode_1_0_11;

    3. //rv32 store指令,opcode是0100011,不同store指令通过func3区分
    4. wire rv32_store    = opcode_6_5_01 & opcode_4_2_000 & opcode_1_0_11;

    5. //madd指令 opcode=1000011,乘加指令

    6. //madd指令是浮点指令的一部分,fmadd.s, fmadd.d, fmadd.q,e203 不支持
    7. // wire rv32_madd     = opcode_6_5_10 & opcode_4_2_000 & opcode_1_0_11;

    8. //branch指令opcode=1100011, bxx指令jalr,jal操作码不同,单独判断
    9. wire rv32_branch   = opcode_6_5_11 & opcode_4_2_000 & opcode_1_0_11;

    10. //浮点数load指令,opcode=0000111,包括fsw,fsd,fsq
    11. //wire rv32_load_fp  = opcode_6_5_00 & opcode_4_2_001 & opcode_1_0_11;

    12. //浮点数store指令,opcode=0100111,包括flw,fld,flq
    13. // wire rv32_store_fp = opcode_6_5_01 & opcode_4_2_001 & opcode_1_0_11;

    14. //msub指令 opcode=1000111,乘减指令
    15. //msub指令是浮点指令的一部分,fmsub.s, fmsub.d, fmsub.q

    16. wire rv32_msub     = opcode_6_5_10 & opcode_4_2_001 & opcode_1_0_11;

    17. //jalr指令的opcode=1100111
    18. wire rv32_jalr     = opcode_6_5_11 & opcode_4_2_001 & opcode_1_0_11;

    19. //opcode为0001011为第一类的定制指令,架构设计者可以实现自己定义的指令
    20. //opcode为0101011为第二类的定制指令,还有第三和第四类的定制指令。

    21. //wire rv32_custom0  = opcode_6_5_00 & opcode_4_2_010 & opcode_1_0_11;
    22. //wire rv32_custom1  = opcode_6_5_01 & opcode_4_2_010 & opcode_1_0_11;

    23. //nmsub指令opcode=1001011, 负乘减操作x[rd]=-rs1*rs2+rs3
    24. //wire rv32_nmsub    = opcode_6_5_10 & opcode_4_2_010 & opcode_1_0_11;

    25. //保留的指令,为了将来扩展用 opcode=1101011
    26. //wire rv32_resved0  = opcode_6_5_11 & opcode_4_2_010 & opcode_1_0_11;

    27. //存储器屏障指令, fence,fence.i, opcode=0001111

    28. wire rv32_miscmem  = opcode_6_5_00 & opcode_4_2_011 & opcode_1_0_11;

    29. //原子指令, opcode=0101111,不同的原子指令,通过func3和func7区分
    30. `ifdef E203_SUPPORT_AMO//{
    31. wire rv32_amo      = opcode_6_5_01 & opcode_4_2_011 & opcode_1_0_11;
    32. `endif//E203_SUPPORT_AMO}
    33. `ifndef E203_SUPPORT_AMO//{
    34. wire rv32_amo      = 1'b0;
    35. `endif//}

    36. //nmadd指令是浮点指令的一部分,fnmadd.s, fnmadd.d, fnmadd.q
    37. wire rv32_nmadd    = opcode_6_5_10 & opcode_4_2_011 & opcode_1_0_11;

    38. //jal指令的opcode=1101111
    39. wire rv32_jal      = opcode_6_5_11 & opcode_4_2_011 & opcode_1_0_11;

    40. //i型的运算指令,opcode=0010011,比如addi

    41. wire rv32_op_imm   = opcode_6_5_00 & opcode_4_2_100 & opcode_1_0_11;

    42. //浮点R型的运算指令, opcode=1010011, 比如add
    43. wire rv32_op       = opcode_6_5_01 & opcode_4_2_100 & opcode_1_0_11;

    44. //R型的运算指令, opcode=0110011, 比如fadd.s
    45. wire rv32_op_fp    = opcode_6_5_10 & opcode_4_2_100 & opcode_1_0_11;

    46. //一些csr指令, opcode=1110011,比如csrrw
    47. wire rv32_system   = opcode_6_5_11 & opcode_4_2_100 & opcode_1_0_11;

    48. //auipc指令,opcode=0010111

    49. wire rv32_auipc    = opcode_6_5_00 & opcode_4_2_101 & opcode_1_0_11;

    50. //lui指令,opcode=0110111
    51. wire rv32_lui      = opcode_6_5_01 & opcode_4_2_101 & opcode_1_0_11;

    52. //第二、三类保留指令
    53. // wire rv32_resved1  = opcode_6_5_10 & opcode_4_2_101 & opcode_1_0_11;
    54. // wire rv32_resved2  = opcode_6_5_11 & opcode_4_2_101 & opcode_1_0_11;

    55. //slliw,srliw,addiw, sraiw等指令的操作码,opcode=0011011,这些都是64位指令

    56. //wire rv32_op_imm_32= opcode_6_5_00 & opcode_4_2_110 & opcode_1_0_11;

    57. //addw,subw,…等64位算术运算指令
    58. // wire rv32_op_32    = opcode_6_5_01 & opcode_4_2_110 & opcode_1_0_11;

    59. //第三,四类定制指令
    60. // wire rv32_custom2  = opcode_6_5_10 & opcode_4_2_110 & opcode_1_0_11;
    61. // wire rv32_custom3  = opcode_6_5_11 & opcode_4_2_110 & opcode_1_0_11;
    复制代码
    1. //c.addispn, opcode=00, func3=000

    2. wire rv16_addi4spn     = opcode_1_0_00 & rv16_func3_000;

    3. //c.lw, opcode=00, func3=010
    4. wire rv16_lw           = opcode_1_0_00 & rv16_func3_010;

    5. //c.sw, opcode=00, func3=110
    6. wire rv16_sw           = opcode_1_0_00 & rv16_func3_110;

    7. //c.addi, opcode=01, func3=000
    8. wire rv16_addi         = opcode_1_0_01 & rv16_func3_000;

    9. //c.jal, opcode=01, func3=001
    10. wire rv16_jal          = opcode_1_0_01 & rv16_func3_001;

    11. //c.li, opcode=01, func3=010
    12. wire rv16_li           = opcode_1_0_01 & rv16_func3_010;

    13. //c.lui是对的,addi16sp还要判断11-7位是否是00010
    14. wire rv16_lui_addi16sp = opcode_1_0_01 & rv16_func3_011;

    15. //一些c.alu指令,比如c.sub等等,opcode=01, func3=100,不同的c.alu指令之间,通过[12-10][6-6]来区分
    16. wire rv16_miscalu      = opcode_1_0_01 & rv16_func3_100;

    17. //c.j指令,opcode=01, func3=101
    18. wire rv16_j            = opcode_1_0_01 & rv16_func3_101

    19. //c.beqz指令,opcode=01, func3=110
    20. wire rv16_beqz         = opcode_1_0_01 & rv16_func3_110;

    21. //c.bnez指令,opcode=01, func3=111
    22. wire rv16_bnez         = opcode_1_0_01 & rv16_func3_111;

    23. //c.slli指令,opcode=10, func3=000
    24. wire rv16_slli         = opcode_1_0_10 & rv16_func3_000;

    25. //c.lwsp指令,opcode=10, func3=010
    26. wire rv16_lwsp         = opcode_1_0_10 & rv16_func3_010;

    27. //c.jalr, c.add,c,mv  opcode=10, func3=100
    28. wire rv16_jalr_mv_add  = opcode_1_0_10 & rv16_func3_100;

    29. //c.swsp指令,opcode=01, func3=101
    30. wire rv16_swsp         = opcode_1_0_10 & rv16_func3_110;

    31. `ifndef E203_HAS_FPU//{
    32. wire rv16_flw          = 1'b0;
    33. wire rv16_fld          = 1'b0;
    34. wire rv16_fsw          = 1'b0;
    35. wire rv16_fsd          = 1'b0;
    36. wire rv16_fldsp        = 1'b0;
    37. wire rv16_flwsp        = 1'b0;
    38. wire rv16_fsdsp        = 1'b0;
    39. wire rv16_fswsp        = 1'b0;
    40. `endif//}

    41. //对c.lwsp,  rd不能为x0

    42. wire rv16_lwsp_ilgl    = rv16_lwsp & rv16_rd_x0;//(RES, rd=0)

    43. //c.nop指令

    44. wire rv16_nop          = rv16_addi
    45.                         & (~rv16_instr[12]) & (rv16_rd_x0) & (rv16_rs2_x0);

    46. //一些c.alu指令

    47. wire rv16_srli         = rv16_miscalu  & (rv16_instr[11:10] == 2'b00);
    48. wire rv16_srai         = rv16_miscalu  & (rv16_instr[11:10] == 2'b01);
    49. wire rv16_andi         = rv16_miscalu  & (rv16_instr[11:10] == 2'b10);

    50. wire rv16_instr_12_is0   = (rv16_instr[12] == 1'b0);
    51. wire rv16_instr_6_2_is0s = (rv16_instr[6:2] == 5'b0);

    52. //对压缩移位指令的合法性判断

    53. wire rv16_sxxi_shamt_legl =
    54.                 rv16_instr_12_is0 //shamt[5] must be zero for RV32C
    55.               & (~(rv16_instr_6_2_is0s)) //shamt[4:0] must be non-zero for RV32C
    56.                 ;
    57. wire rv16_sxxi_shamt_ilgl =  (rv16_slli | rv16_srli | rv16_srai) & (~rv16_sxxi_shamt_legl);

    58. wire rv16_addi16sp     = rv16_lui_addi16sp & rv32_rd_x2;
    59. wire rv16_lui          = rv16_lui_addi16sp & (~rv32_rd_x0) & (~rv32_rd_x2);

    60. //C.LI is only valid when rd!=x0.
    61. wire rv16_li_ilgl = rv16_li & (rv16_rd_x0);
    62. //C.LUI is only valid when rd!=x0 or x2, and when the immediate is not equal to zero.
    63. wire rv16_lui_ilgl = rv16_lui & (rv16_rd_x0 | rv16_rd_x2 | (rv16_instr_6_2_is0s & rv16_instr_12_is0));

    64. wire rv16_li_lui_ilgl = rv16_li_ilgl | rv16_lui_ilgl;

    65. wire rv16_addi4spn_ilgl = rv16_addi4spn & (rv16_instr_12_is0 & rv16_rd_x0 & opcode_6_5_00);//(RES, nzimm=0, bits[12:5])
    66. wire rv16_addi16sp_ilgl = rv16_addi16sp & rv16_instr_12_is0 & rv16_instr_6_2_is0s; //(RES, nzimm=0, bits 12,6:2)

    67. wire rv16_subxororand  = rv16_miscalu  & (rv16_instr[12:10] == 3'b011);//
    68. wire rv16_sub          = rv16_subxororand & (rv16_instr[6:5] == 2'b00);//
    69. wire rv16_xor          = rv16_subxororand & (rv16_instr[6:5] == 2'b01);//
    70. wire rv16_or           = rv16_subxororand & (rv16_instr[6:5] == 2'b10);//
    71. wire rv16_and          = rv16_subxororand & (rv16_instr[6:5] == 2'b11);//

    72. wire rv16_jr           = rv16_jalr_mv_add //
    73.                         & (~rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);// The RES rs1=0 illegal is already covered here
    74. wire rv16_mv           = rv16_jalr_mv_add //
    75.                         & (~rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);
    76. wire rv16_ebreak       = rv16_jalr_mv_add //
    77.                         & (rv16_instr[12]) & (rv16_rd_x0) & (rv16_rs2_x0);
    78. wire rv16_jalr         = rv16_jalr_mv_add //
    79.                         & (rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);
    80. wire rv16_add          = rv16_jalr_mv_add //
    81.                         & (rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);





    82. // ===========================================================================
    83. // Branch Instructions
    84. wire rv32_beq      = rv32_branch & rv32_func3_000;
    85. wire rv32_bne      = rv32_branch & rv32_func3_001;
    86. wire rv32_blt      = rv32_branch & rv32_func3_100;
    87. wire rv32_bgt      = rv32_branch & rv32_func3_101;
    88. wire rv32_bltu     = rv32_branch & rv32_func3_110;
    89. wire rv32_bgtu     = rv32_branch & rv32_func3_111;

    90. // ===========================================================================
    91. // System Instructions
    92. wire rv32_ecall    = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0000_0000_0000);
    93. wire rv32_ebreak   = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0000_0000_0001);
    94. wire rv32_mret     = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0011_0000_0010);
    95. wire rv32_dret     = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0111_1011_0010);
    96. wire rv32_wfi      = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0001_0000_0101);
    97. // We dont implement the WFI and MRET illegal exception when the rs and rd is not zeros

    98. wire rv32_csrrw    = rv32_system & rv32_func3_001;
    99. wire rv32_csrrs    = rv32_system & rv32_func3_010;
    100. wire rv32_csrrc    = rv32_system & rv32_func3_011;
    101. wire rv32_csrrwi   = rv32_system & rv32_func3_101;
    102. wire rv32_csrrsi   = rv32_system & rv32_func3_110;
    103. wire rv32_csrrci   = rv32_system & rv32_func3_111;

    104. wire rv32_dret_ilgl = rv32_dret & (~dbg_mode);

    105. wire rv32_ecall_ebreak_ret_wfi = rv32_system & rv32_func3_000;
    106. wire rv32_csr          = rv32_system & (~rv32_func3_000);


    107. // ============================================================
    复制代码
    1. //c.addispn, opcode=00, func3=000
    2. wire rv16_addi4spn     = opcode_1_0_00 & rv16_func3_000;

    3. //c.lw, opcode=00, func3=010
    4. wire rv16_lw           = opcode_1_0_00 & rv16_func3_010;

    5. //c.sw, opcode=00, func3=110
    6. wire rv16_sw           = opcode_1_0_00 & rv16_func3_110;

    7. //c.addi, opcode=01, func3=000
    8. wire rv16_addi         = opcode_1_0_01 & rv16_func3_000;

    9. //c.jal, opcode=01, func3=001
    10. wire rv16_jal          = opcode_1_0_01 & rv16_func3_001;

    11. //c.li, opcode=01, func3=010
    12. wire rv16_li           = opcode_1_0_01 & rv16_func3_010;

    13. //addi16sp还要判断11-7位是否是00010
    14. wire rv16_lui_addi16sp = opcode_1_0_01 & rv16_func3_011;

    15. //一些c.alu指令,比如c.sub等等,opcode=01, func3=100,不同的c.alu指令之间,通过[12-10][6-6]来区分
    16. wire rv16_miscalu      = opcode_1_0_01 & rv16_func3_100;

    17. //c.j指令,opcode=01, func3=101
    18. wire rv16_j            = opcode_1_0_01 & rv16_func3_101

    19. //c.beqz指令,opcode=01, func3=110
    20. wire rv16_beqz         = opcode_1_0_01 & rv16_func3_110;

    21. //c.bnez指令,opcode=01, func3=111
    22. wire rv16_bnez         = opcode_1_0_01 & rv16_func3_111;

    23. //c.slli指令,opcode=10, func3=000
    24. wire rv16_slli         = opcode_1_0_10 & rv16_func3_000;

    25. //c.lwsp指令,opcode=10, func3=010
    26. wire rv16_lwsp         = opcode_1_0_10 & rv16_func3_010;

    27. //c.jalr, c.add,c,mv  opcode=10, func3=100
    28. wire rv16_jalr_mv_add  = opcode_1_0_10 & rv16_func3_100;

    29. //c.swsp指令,opcode=01, func3=101
    30. wire rv16_swsp         = opcode_1_0_10 & rv16_func3_110;

    31. `ifndef E203_HAS_FPU//{
    32. wire rv16_flw          = 1'b0;
    33. wire rv16_fld          = 1'b0;
    34. wire rv16_fsw          = 1'b0;
    35. wire rv16_fsd          = 1'b0;
    36. wire rv16_fldsp        = 1'b0;
    37. wire rv16_flwsp        = 1'b0;
    38. wire rv16_fsdsp        = 1'b0;
    39. wire rv16_fswsp        = 1'b0;
    40. `endif//}

    41. //对c.lwsp,  rd不能为x0

    42. wire rv16_lwsp_ilgl    = rv16_lwsp & rv16_rd_x0;//(RES, rd=0)

    43. //c.nop指令,imm[6:2]位用rs2来代替,他们位置是相同的

    44. wire rv16_nop          = rv16_addi
    45.                         & (~rv16_instr[12]) & (rv16_rd_x0) & (rv16_rs2_x0);

    46. //一些c.alu指令

    47. wire rv16_srli         = rv16_miscalu  & (rv16_instr[11:10] == 2'b00);
    48. wire rv16_srai         = rv16_miscalu  & (rv16_instr[11:10] == 2'b01);
    49. wire rv16_andi         = rv16_miscalu  & (rv16_instr[11:10] == 2'b10);

    50. wire rv16_instr_12_is0   = (rv16_instr[12] == 1'b0);
    51. wire rv16_instr_6_2_is0s = (rv16_instr[6:2] == 5'b0);

    52. //对压缩移位指令的合法性判断

    53. wire rv16_sxxi_shamt_legl =
    54.                 rv16_instr_12_is0 //shamt[5] must be zero for RV32C
    55.               & (~(rv16_instr_6_2_is0s)) //shamt[4:0] must be non-zero for RV32C
    56.                 ;
    57. wire rv16_sxxi_shamt_ilgl =  (rv16_slli | rv16_srli | rv16_srai) & (~rv16_sxxi_shamt_legl);

    58. wire rv16_addi16sp     = rv16_lui_addi16sp & rv32_rd_x2;
    59. wire rv16_lui          = rv16_lui_addi16sp & (~rv32_rd_x0) & (~rv32_rd_x2);

    60. //C.LI is only valid when rd!=x0.
    61. wire rv16_li_ilgl = rv16_li & (rv16_rd_x0);
    62. //C.LUI is only valid when rd!=x0 or x2, and when the immediate is not equal to zero.
    63. wire rv16_lui_ilgl = rv16_lui & (rv16_rd_x0 | rv16_rd_x2 | (rv16_instr_6_2_is0s & rv16_instr_12_is0));

    64. wire rv16_li_lui_ilgl = rv16_li_ilgl | rv16_lui_ilgl;

    65. wire rv16_addi4spn_ilgl = rv16_addi4spn & (rv16_instr_12_is0 & rv16_rd_x0 & opcode_6_5_00);//(RES, nzimm=0, bits[12:5])
    66. wire rv16_addi16sp_ilgl = rv16_addi16sp & rv16_instr_12_is0 & rv16_instr_6_2_is0s; //(RES, nzimm=0, bits 12,6:2)

    67. wire rv16_subxororand  = rv16_miscalu  & (rv16_instr[12:10] == 3'b011);//
    68. wire rv16_sub          = rv16_subxororand & (rv16_instr[6:5] == 2'b00);//
    69. wire rv16_xor          = rv16_subxororand & (rv16_instr[6:5] == 2'b01);//
    70. wire rv16_or           = rv16_subxororand & (rv16_instr[6:5] == 2'b10);//
    71. wire rv16_and          = rv16_subxororand & (rv16_instr[6:5] == 2'b11);//

    72. wire rv16_jr           = rv16_jalr_mv_add //
    73.                         & (~rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);// The RES rs1=0 illegal is already covered here
    74. wire rv16_mv           = rv16_jalr_mv_add //
    75.                         & (~rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);
    76. wire rv16_ebreak       = rv16_jalr_mv_add //
    77.                         & (rv16_instr[12]) & (rv16_rd_x0) & (rv16_rs2_x0);
    78. wire rv16_jalr         = rv16_jalr_mv_add //
    79.                         & (rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);
    80. wire rv16_add          = rv16_jalr_mv_add //
    81.                         & (rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);
    复制代码
    32位系统指令,csr指令以及分支指令判断。
    1. // ===========================================================================
    2. // Branch Instructions
    3. wire rv32_beq      = rv32_branch & rv32_func3_000;
    4. wire rv32_bne      = rv32_branch & rv32_func3_001;
    5. wire rv32_blt      = rv32_branch & rv32_func3_100;
    6. wire rv32_bgt      = rv32_branch & rv32_func3_101;
    7. wire rv32_bltu     = rv32_branch & rv32_func3_110;
    8. wire rv32_bgtu     = rv32_branch & rv32_func3_111;

    9. // ===========================================================================
    10. // System Instructions
    11. wire rv32_ecall    = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0000_0000_0000);
    12. wire rv32_ebreak   = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0000_0000_0001);
    13. wire rv32_mret     = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0011_0000_0010);
    14. wire rv32_dret     = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0111_1011_0010);
    15. wire rv32_wfi      = rv32_system & rv32_func3_000 & (rv32_instr[31:20] == 12'b0001_0000_0101);
    16. // We dont implement the WFI and MRET illegal exception when the rs and rd is not zeros

    17. wire rv32_csrrw    = rv32_system & rv32_func3_001;
    18. wire rv32_csrrs    = rv32_system & rv32_func3_010;
    19. wire rv32_csrrc    = rv32_system & rv32_func3_011;
    20. wire rv32_csrrwi   = rv32_system & rv32_func3_101;
    21. wire rv32_csrrsi   = rv32_system & rv32_func3_110;
    22. wire rv32_csrrci   = rv32_system & rv32_func3_111;

    23. //如果为debug模式,则忽视dret不合法的判断
    24. wire rv32_dret_ilgl = rv32_dret & (~dbg_mode);

    25. wire rv32_ecall_ebreak_ret_wfi = rv32_system & rv32_func3_000;
    26. wire rv32_csr          = rv32_system & (~rv32_func3_000);


    27. // ============================================================
    复制代码
    译码模块输入包括信息总线,信息总线中包含一个3位的grp信息,EXU单元会根据这个grp把解码后的信号派遣 (dispatch)到该单元进行后续的的处理。E203并不包括EAI和FPU单元,其它5个单元是ALU单元的子单元。不同的指令会在这些子单元中进行后续的执行操作。
    国内芯片技术交流-E203 译码模块(1)risc-v单片机中文社区(2)
    跳转和系统指令被BJP单元处理,
    下面代码生成BJP单元所需的信息总线(Info Bus),BJP单元信息总线总共17位。每位表示的意思如下,其中,grp为010:
    国内芯片技术交流-E203 译码模块(1)risc-v单片机中文社区(3)
    1. // The Branch and system group of instructions will be handled by BJP

    2. assign dec_jal     = rv32_jal    | rv16_jal  | rv16_j;
    3. assign dec_jalr    = rv32_jalr   | rv16_jalr | rv16_jr;
    4. assign dec_bxx     = rv32_branch | rv16_beqz | rv16_bnez;
    5. assign dec_bjp     = dec_jal | dec_jalr | dec_bxx;


    6. wire rv32_fence  ;
    7. wire rv32_fence_i;
    8. wire rv32_fence_fencei;

    9. //判定当前指令是否是bjp指令
    10. wire bjp_op = dec_bjp | rv32_mret | (rv32_dret & (~rv32_dret_ilgl)) | rv32_fence_fencei;

    11. //生成bjp信息总线信号

    12. wire [`E203_DECINFO_BJP_WIDTH-1:0] bjp_info_bus;
    13. assign bjp_info_bus[`E203_DECINFO_GRP    ]    = `E203_DECINFO_GRP_BJP;
    14. assign bjp_info_bus[`E203_DECINFO_RV32   ]    = rv32;
    15. assign bjp_info_bus[`E203_DECINFO_BJP_JUMP ]  = dec_jal | dec_jalr;
    16. assign bjp_info_bus[`E203_DECINFO_BJP_BPRDT]  = i_prdt_taken;
    17. assign bjp_info_bus[`E203_DECINFO_BJP_BEQ  ]  = rv32_beq | rv16_beqz;
    18. assign bjp_info_bus[`E203_DECINFO_BJP_BNE  ]  = rv32_bne | rv16_bnez;
    19. assign bjp_info_bus[`E203_DECINFO_BJP_BLT  ]  = rv32_blt;
    20. assign bjp_info_bus[`E203_DECINFO_BJP_BGT  ]  = rv32_bgt ;
    21. assign bjp_info_bus[`E203_DECINFO_BJP_BLTU ]  = rv32_bltu;
    22. assign bjp_info_bus[`E203_DECINFO_BJP_BGTU ]  = rv32_bgtu;
    23. assign bjp_info_bus[`E203_DECINFO_BJP_BXX  ]  = dec_bxx;
    24. assign bjp_info_bus[`E203_DECINFO_BJP_MRET ]  = rv32_mret;
    25. assign bjp_info_bus[`E203_DECINFO_BJP_DRET ]  = rv32_dret;
    26. assign bjp_info_bus[`E203_DECINFO_BJP_FENCE ]  = rv32_fence;
    27. assign bjp_info_bus[`E203_DECINFO_BJP_FENCEI]  = rv32_fence_i;
    复制代码




    上一篇:蜂鸟E203 IFU模块
    下一篇:E203 译码模块(2)
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

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



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

    GMT+8, 2024-4-25 19:45 , Processed in 1.459258 second(s), 48 queries .

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