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

E203 译码模块(2)

[复制链接]

  离线 

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

    [LV.3]

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

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

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

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

    E203 译码模块(3)

    常用的alu算术运算指令(包括ecall和 ebreak)在regular alu单元处理。regular alu单元为alu单元的一个子单元。regular单元的信息总线共21位,格式如下图所示,其中grp为000:
    国内芯片技术交流-E203 译码模块(2)risc-v单片机中文社区(1)

    下面的代码产生regular alu单元的信息总线。
    1. // ALU Instructions
    2.    wire rv32_addi     = rv32_op_imm & rv32_func3_000;
    3.    wire rv32_slti     = rv32_op_imm & rv32_func3_010;
    4.    wire rv32_sltiu    = rv32_op_imm & rv32_func3_011;
    5.    wire rv32_xori     = rv32_op_imm & rv32_func3_100;
    6.    wire rv32_ori      = rv32_op_imm & rv32_func3_110;
    7.    wire rv32_andi     = rv32_op_imm & rv32_func3_111;

    8.   wire rv32_slli     = rv32_op_imm & rv32_func3_001 & (rv32_instr[31:26] == 6'b000000);
    9.    wire rv32_srli     = rv32_op_imm & rv32_func3_101 & (rv32_instr[31:26] == 6'b000000);
    10.    wire rv32_srai     = rv32_op_imm & rv32_func3_101 & (rv32_instr[31:26] == 6'b010000);

    11.   //对一些移位指令,shamt[5] must be zero for RV32I,在RV64I中才可以不为0

    12.   wire rv32_sxxi_shamt_legl = (rv32_instr[25] == 1'b0);
    13.    wire rv32_sxxi_shamt_ilgl =  (rv32_slli | rv32_srli | rv32_srai) & (~rv32_sxxi_shamt_legl);

    14.   wire rv32_add      = rv32_op     & rv32_func3_000 & rv32_func7_0000000;
    15.    wire rv32_sub      = rv32_op     & rv32_func3_000 & rv32_func7_0100000;
    16.    wire rv32_sll      = rv32_op     & rv32_func3_001 & rv32_func7_0000000;
    17.    wire rv32_slt      = rv32_op     & rv32_func3_010 & rv32_func7_0000000;
    18.    wire rv32_sltu     = rv32_op     & rv32_func3_011 & rv32_func7_0000000;
    19.    wire rv32_xor      = rv32_op     & rv32_func3_100 & rv32_func7_0000000;
    20.    wire rv32_srl      = rv32_op     & rv32_func3_101 & rv32_func7_0000000;
    21.    wire rv32_sra      = rv32_op     & rv32_func3_101 & rv32_func7_0100000;
    22.    wire rv32_or       = rv32_op     & rv32_func3_110 & rv32_func7_0000000;
    23.   wire rv32_and      = rv32_op     & rv32_func3_111 & rv32_func7_0000000;

    24.   //对rv32 nop指令,31-20位为0

    25.   wire rv32_nop      = rv32_addi & rv32_rs1_x0 & rv32_rd_x0 & (~(|rv32_instr[31:20]));
    26.    // The ALU group of instructions will be handled by 1cycle ALU-datapath
    27.    wire ecall_ebreak = rv32_ecall | rv32_ebreak | rv16_ebreak;
    28.   //当前指令是alu_op指令
    29.   wire alu_op = (~rv32_sxxi_shamt_ilgl) & (~rv16_sxxi_shamt_ilgl)
    30.                & (~rv16_li_lui_ilgl) & (~rv16_addi4spn_ilgl) & (~rv16_addi16sp_ilgl) &
    31.                ( rv32_op_imm
    32.                | rv32_op & (~rv32_func7_0000001) // Exclude the MULDIV
    33.                | rv32_auipc
    34.                | rv32_lui
    35.                | rv16_addi4spn
    36.                | rv16_addi
    37.                | rv16_lui_addi16sp
    38.                | rv16_li | rv16_mv
    39.                | rv16_slli
    40.                | rv16_miscalu
    41.                | rv16_add
    42.                | rv16_nop | rv32_nop
    43.                | rv32_wfi // We just put WFI into ALU and do nothing in ALU
    44.                | ecall_ebreak)
    45.                ;
    46.    wire need_imm;
    47.    wire [`E203_DECINFO_ALU_WIDTH-1:0] alu_info_bus;
    48.    assign alu_info_bus[`E203_DECINFO_GRP    ]    = `E203_DECINFO_GRP_ALU;
    49.    assign alu_info_bus[`E203_DECINFO_RV32   ]    = rv32;
    50.    assign alu_info_bus[`E203_DECINFO_ALU_ADD]    = rv32_add  | rv32_addi | rv32_auipc |
    51.                                                    rv16_addi4spn | rv16_addi | rv16_addi16sp | rv16_add |
    52.                              // We also decode LI and MV as the add instruction, becuase
    53.                              //   they all add x0 with a RS2 or Immeidate, and then write into RD
    54.                                                    rv16_li | rv16_mv;
    55.    assign alu_info_bus[`E203_DECINFO_ALU_SUB]    = rv32_sub  | rv16_sub;
    56.    assign alu_info_bus[`E203_DECINFO_ALU_SLT]    = rv32_slt  | rv32_slti;
    57.    assign alu_info_bus[`E203_DECINFO_ALU_SLTU]   = rv32_sltu | rv32_sltiu;
    58.    assign alu_info_bus[`E203_DECINFO_ALU_XOR]    = rv32_xor  | rv32_xori | rv16_xor;
    59.    assign alu_info_bus[`E203_DECINFO_ALU_SLL]    = rv32_sll  | rv32_slli | rv16_slli;
    60.    assign alu_info_bus[`E203_DECINFO_ALU_SRL]    = rv32_srl  | rv32_srli | rv16_srli;
    61.    assign alu_info_bus[`E203_DECINFO_ALU_SRA]    = rv32_sra  | rv32_srai | rv16_srai;
    62.    assign alu_info_bus[`E203_DECINFO_ALU_OR ]    = rv32_or   | rv32_ori  | rv16_or;
    63.    assign alu_info_bus[`E203_DECINFO_ALU_AND]    = rv32_and  | rv32_andi | rv16_andi | rv16_and;
    64.    assign alu_info_bus[`E203_DECINFO_ALU_LUI]    = rv32_lui  | rv16_lui;
    65.    assign alu_info_bus[`E203_DECINFO_ALU_OP2IMM] = need_imm;
    66.    assign alu_info_bus[`E203_DECINFO_ALU_OP1PC ] = rv32_auipc;
    67.    assign alu_info_bus[`E203_DECINFO_ALU_NOP ]   = rv16_nop | rv32_nop;
    68.    assign alu_info_bus[`E203_DECINFO_ALU_ECAL ]  = rv32_ecall;
    69.    assign alu_info_bus[`E203_DECINFO_ALU_EBRK ]  = rv32_ebreak | rv16_ebreak;
    70.    assign alu_info_bus[`E203_DECINFO_ALU_WFI  ]  = rv32_wfi;
    复制代码

    alu中包含一个csr读写控制子单元,所有csr指令都在这个子单元中执行。下面csr读写控制单元的信息总线,其中grp为011
    国内芯片技术交流-E203 译码模块(2)risc-v单片机中文社区(2)

    1. wire csr_op = rv32_csr;
    2.    wire [`E203_DECINFO_CSR_WIDTH-1:0] csr_info_bus;
    3.    assign csr_info_bus[`E203_DECINFO_GRP    ]    = `E203_DECINFO_GRP_CSR;
    4.    assign csr_info_bus[`E203_DECINFO_RV32   ]    = rv32;
    5.    assign csr_info_bus[`E203_DECINFO_CSR_CSRRW ] = rv32_csrrw | rv32_csrrwi;
    6.    assign csr_info_bus[`E203_DECINFO_CSR_CSRRS ] = rv32_csrrs | rv32_csrrsi;
    7.    assign csr_info_bus[`E203_DECINFO_CSR_CSRRC ] = rv32_csrrc | rv32_csrrci;
    8.    assign csr_info_bus[`E203_DECINFO_CSR_RS1IMM] = rv32_csrrwi | rv32_csrrsi | rv32_csrrci;
    9.    assign csr_info_bus[`E203_DECINFO_CSR_ZIMMM ] = rv32_rs1;
    10.    assign csr_info_bus[`E203_DECINFO_CSR_RS1IS0] = rv32_rs1_x0;
    11.    assign csr_info_bus[`E203_DECINFO_CSR_CSRIDX] = rv32_instr[31:20];
    复制代码
    alu中乘法除法子单元进行乘法,除法运算,该单元的信息总线格式为:
    国内芯片技术交流-E203 译码模块(2)risc-v单片机中文社区(3)

    1. // MUL/DIV Instructions
    2.    wire rv32_mul      = rv32_op     & rv32_func3_000 & rv32_func7_0000001;
    3.    wire rv32_mulh     = rv32_op     & rv32_func3_001 & rv32_func7_0000001;
    4.    wire rv32_mulhsu   = rv32_op     & rv32_func3_010 & rv32_func7_0000001;
    5.    wire rv32_mulhu    = rv32_op     & rv32_func3_011 & rv32_func7_0000001;
    6.    wire rv32_div      = rv32_op     & rv32_func3_100 & rv32_func7_0000001;
    7.    wire rv32_divu     = rv32_op     & rv32_func3_101 & rv32_func7_0000001;
    8.    wire rv32_rem      = rv32_op     & rv32_func3_110 & rv32_func7_0000001;
    9.    wire rv32_remu     = rv32_op     & rv32_func3_111 & rv32_func7_0000001;

    10.    // The MULDIV group of instructions will be handled by MUL-DIV-datapath
    11.    `ifdef E203_SUPPORT_MULDIV//{
    12.    wire muldiv_op = rv32_op & rv32_func7_0000001;
    13.    `endif//}
    14.    `ifndef E203_SUPPORT_MULDIV//{
    15.    wire muldiv_op = 1'b0;
    16.    `endif//}

    17.   wire [`E203_DECINFO_MULDIV_WIDTH-1:0] muldiv_info_bus;
    18.    assign muldiv_info_bus[`E203_DECINFO_GRP          ] = `E203_DECINFO_GRP_MULDIV;
    19.    assign muldiv_info_bus[`E203_DECINFO_RV32         ] = rv32        ;
    20.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_MUL   ] = rv32_mul    ;
    21.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_MULH  ] = rv32_mulh   ;
    22.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_MULHSU] = rv32_mulhsu ;
    23.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_MULHU ] = rv32_mulhu  ;
    24.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_DIV   ] = rv32_div    ;
    25.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_DIVU  ] = rv32_divu   ;
    26.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_REM   ] = rv32_rem    ;
    27.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_REMU  ] = rv32_remu   ;
    28.    assign muldiv_info_bus[`E203_DECINFO_MULDIV_B2B   ] = i_muldiv_b2b;

    29.   assign dec_mulhsu = rv32_mulh | rv32_mulhsu | rv32_mulhu;
    30.    assign dec_mul    = rv32_mul;
    31.    assign dec_div    = rv32_div ;
    32.    assign dec_divu   = rv32_divu;
    33.    assign dec_rem    = rv32_rem;
    34.    assign dec_remu   = rv32_remu;
    复制代码
    alu中的AGU子单元,主要负责Load,store指令和A扩展指令的地址生成,以及A扩展指令的微操作拆分和执行。
        传输到AGU模块的信息总线格式为:
    国内芯片技术交流-E203 译码模块(2)risc-v单片机中文社区(4)
    1. // ===========================================================================
    2.    // Load/Store Instructions
    3.    wire rv32_lb       = rv32_load   & rv32_func3_000;
    4.    wire rv32_lh       = rv32_load   & rv32_func3_001;
    5.    wire rv32_lw       = rv32_load   & rv32_func3_010;
    6.    wire rv32_lbu      = rv32_load   & rv32_func3_100;
    7.    wire rv32_lhu      = rv32_load   & rv32_func3_101;

    8.   wire rv32_sb       = rv32_store  & rv32_func3_000;
    9.    wire rv32_sh       = rv32_store  & rv32_func3_001;
    10.    wire rv32_sw       = rv32_store  & rv32_func3_010;


    11.    // ===========================================================================
    12.    // Atomic Instructions
    13.    `ifdef E203_SUPPORT_AMO//{
    14.    wire rv32_lr_w      = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00010);
    15.    wire rv32_sc_w      = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00011);
    16.    wire rv32_amoswap_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00001);
    17.    wire rv32_amoadd_w  = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00000);
    18.    wire rv32_amoxor_w  = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b00100);
    19.    wire rv32_amoand_w  = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b01100);
    20.    wire rv32_amoor_w   = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b01000);
    21.    wire rv32_amomin_w  = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b10000);
    22.    wire rv32_amomax_w  = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b10100);
    23.    wire rv32_amominu_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b11000);
    24.    wire rv32_amomaxu_w = rv32_amo & rv32_func3_010 & (rv32_func7[6:2] == 5'b11100);

    25.   `endif//E203_SUPPORT_AMO}
    26.    `ifndef E203_SUPPORT_AMO//{
    27.    wire rv32_lr_w      = 1'b0;
    28.    wire rv32_sc_w      = 1'b0;
    29.    wire rv32_amoswap_w = 1'b0;
    30.    wire rv32_amoadd_w  = 1'b0;
    31.    wire rv32_amoxor_w  = 1'b0;
    32.    wire rv32_amoand_w  = 1'b0;
    33.    wire rv32_amoor_w   = 1'b0;
    34.    wire rv32_amomin_w  = 1'b0;
    35.    wire rv32_amomax_w  = 1'b0;
    36.    wire rv32_amominu_w = 1'b0;
    37.    wire rv32_amomaxu_w = 1'b0;

    38.   `endif//}

    39.   wire   amoldst_op = rv32_amo | rv32_load | rv32_store | rv16_lw | rv16_sw | (rv16_lwsp & (~rv16_lwsp_ilgl)) | rv16_swsp;
    40.      // The RV16 always is word
    41.    wire [1:0] lsu_info_size  = rv32 ? rv32_func3[1:0] : 2'b10;
    42.      // The RV16 always is signed
    43.    wire       lsu_info_usign = rv32? rv32_func3[2] : 1'b0;

    44.   wire [`E203_DECINFO_AGU_WIDTH-1:0] agu_info_bus;
    45.    assign agu_info_bus[`E203_DECINFO_GRP    ] = `E203_DECINFO_GRP_AGU;
    46.    assign agu_info_bus[`E203_DECINFO_RV32   ] = rv32;
    47.    assign agu_info_bus[`E203_DECINFO_AGU_LOAD   ] = rv32_load  | rv32_lr_w | rv16_lw | rv16_lwsp;
    48.    assign agu_info_bus[`E203_DECINFO_AGU_STORE  ] = rv32_store | rv32_sc_w | rv16_sw | rv16_swsp;
    49.    assign agu_info_bus[`E203_DECINFO_AGU_SIZE   ] = lsu_info_size;
    50.    assign agu_info_bus[`E203_DECINFO_AGU_USIGN  ] = lsu_info_usign;
    51.    assign agu_info_bus[`E203_DECINFO_AGU_EXCL   ] = rv32_lr_w | rv32_sc_w;
    52.    assign agu_info_bus[`E203_DECINFO_AGU_AMO    ] = rv32_amo & (~(rv32_lr_w | rv32_sc_w));// We seperated the EXCL out of AMO in LSU handling
    53.    assign agu_info_bus[`E203_DECINFO_AGU_AMOSWAP] = rv32_amoswap_w;
    54.    assign agu_info_bus[`E203_DECINFO_AGU_AMOADD ] = rv32_amoadd_w ;
    55.    assign agu_info_bus[`E203_DECINFO_AGU_AMOAND ] = rv32_amoand_w ;
    56.    assign agu_info_bus[`E203_DECINFO_AGU_AMOOR  ] = rv32_amoor_w ;
    57.    assign agu_info_bus[`E203_DECINFO_AGU_AMOXOR ] = rv32_amoxor_w  ;
    58.    assign agu_info_bus[`E203_DECINFO_AGU_AMOMAX ] = rv32_amomax_w ;
    59.    assign agu_info_bus[`E203_DECINFO_AGU_AMOMIN ] = rv32_amomin_w ;
    60.    assign agu_info_bus[`E203_DECINFO_AGU_AMOMAXU] = rv32_amomaxu_w;
    61.    assign agu_info_bus[`E203_DECINFO_AGU_AMOMINU] = rv32_amominu_w;
    62.    assign agu_info_bus[`E203_DECINFO_AGU_OP2IMM ] = need_imm;
    复制代码
    指令全为0和全为1是非法的指令,下面的代码判定指令是否为全0和全1。
    1. // Reuse the common signals as much as possible to save gatecounts
    2.    wire rv32_all0s_ilgl  = rv32_func7_0000000
    3.                          & rv32_rs2_x0
    4.                          & rv32_rs1_x0
    5.                          & rv32_func3_000
    6.                          & rv32_rd_x0
    7.                          & opcode_6_5_00
    8.                          & opcode_4_2_000
    9.                          & (opcode[1:0] == 2'b00);

    10.   wire rv32_all1s_ilgl  = rv32_func7_1111111
    11.                          & rv32_rs2_x31
    12.                          & rv32_rs1_x31
    13.                          & rv32_func3_111
    14.                          & rv32_rd_x31
    15.                          & opcode_6_5_11
    16.                          & opcode_4_2_111
    17.                          & (opcode[1:0] == 2'b11);

    18.   wire rv16_all0s_ilgl  = rv16_func3_000 //rv16_func3  = rv32_instr[15:13];
    19.                          & rv32_func3_000 //rv32_func3  = rv32_instr[14:12];
    20.                          & rv32_rd_x0     //rv32_rd     = rv32_instr[11:7];
    21.                          & opcode_6_5_00
    22.                          & opcode_4_2_000
    23.                          & (opcode[1:0] == 2'b00);

    24.   wire rv16_all1s_ilgl  = rv16_func3_111
    25.                          & rv32_func3_111
    26.                          & rv32_rd_x31
    27.                          & opcode_6_5_11
    28.                          & opcode_4_2_111
    29.                          & (opcode[1:0] == 2'b11);

    30.    wire rv_all0s1s_ilgl = rv32 ?  (rv32_all0s_ilgl | rv32_all1s_ilgl)
    31.                                :  (rv16_all0s_ilgl | rv16_all1s_ilgl);
    复制代码
    以下的代码判断指令是否需要寄存器操作数1,寄存器操作数2,是否需要写目的寄存器。
    1. // All the RV32IMA need RD register except the
    2.    //   * Branch, Store,
    3.    //   * fence, fence_i
    4.    //   * ecall, ebreak  
    5.    wire rv32_need_rd =
    6.                        (~rv32_rd_x0) & (
    7.                      (
    8.                        (~rv32_branch) & (~rv32_store)
    9.                      & (~rv32_fence_fencei)
    10.                      & (~rv32_ecall_ebreak_ret_wfi)
    11.                      )
    12.                     );

    13.   // All the RV32IMA need RS1 register except the
    14.    //   * lui
    15.    //   * auipc
    16.    //   * jal
    17.    //   * fence, fence_i
    18.    //   * ecall, ebreak  
    19.    //   * csrrwi
    20.    //   * csrrsi
    21.    //   * csrrci
    22.    wire rv32_need_rs1 =
    23.                        (~rv32_rs1_x0) & (
    24.                      (
    25.                        (~rv32_lui)
    26.                      & (~rv32_auipc)
    27.                      & (~rv32_jal)
    28.                      & (~rv32_fence_fencei)
    29.                      & (~rv32_ecall_ebreak_ret_wfi)
    30.                      & (~rv32_csrrwi)
    31.                      & (~rv32_csrrsi)
    32.                      & (~rv32_csrrci)
    33.                      )
    34.                    );

    35.    // Following RV32IMA instructions need RS2 register
    36.    //   * branch
    37.    //   * store
    38.    //   * rv32_op
    39.    //   * rv32_amo except the rv32_lr_w
    40.    wire rv32_need_rs2 = (~rv32_rs2_x0) & (
    41.                  (
    42.                   (rv32_branch)
    43.                 | (rv32_store)
    44.                 | (rv32_op)
    45.                 | (rv32_amo & (~rv32_lr_w))
    46.                   )
    47.                   );
    复制代码







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

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

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



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

    GMT+8, 2024-3-29 10:34 , Processed in 0.596835 second(s), 48 queries .

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