E203 譯碼模塊(1)


      E203是兩級流水線結構,第一級是IFU進行取指操作,第二級包括譯碼、執行、交付和寫回等功能。架構圖如下:

       https://www.cnblogs.com/images/cnblogs_com/mikewolf2002/1519640/o_pipeline.jpg

     譯碼模塊就是把機器碼翻譯成對應的輸出功能。E203支持RV32IMAC,它的譯碼器模塊是純的組合電路實現,相對比較簡單。只要熟悉了RiscV的指令規范,很容易看懂。


     譯碼模塊的輸入信號來自於IFU模塊,包括以下信號:

input  [`E203_INSTR_SIZE-1:0] i_instr, //來自IFU的32位指令
input  [`E203_PC_SIZE-1:0] i_pc,       //來自IFU的當前指令PC
input  i_prdt_taken,           //預測需要跳轉,來自IFU模塊的分支預測單元,對分支跳轉指令有用,如果當前指令為分支跳轉指令,該信號會被傳遞到相應的info_bus
 input  i_misalgn,              // 表示當前指令遇到了分支跳轉異常
 input  i_buserr,               // 表面當前指令遭遇了取指存儲器訪問錯誤
 input  i_muldiv_b2b,           // 前后臨接的mul和div指令時置1,如果當前指令為乘法除法指令,該信號傳遞到相應的info_bus

input  dbg_mode,   //debug模式下,忽視dret指令異常的情況

      譯碼模塊的輸出包括以下信號:

output dec_rs1x0, // 該指令源操作數1為x0
 output dec_rs2x0, // 該指令源操作數2為x0
 output dec_rs1en, //該指令需要讀取源操作數1
 output dec_rs2en, //該指令需要讀取源操作數2
 output dec_rdwen, //該指令需要寫結果操作數到目的寄存器
 output [`E203_RFIDX_WIDTH-1:0] dec_rs1idx,  //源操作數1的寄存器索引
 output [`E203_RFIDX_WIDTH-1:0] dec_rs2idx, //源操作數2的寄存器索引
output [`E203_RFIDX_WIDTH-1:0] dec_rdidx,  //目的寄存器索引
 output [`E203_DECINFO_WIDTH-1:0] dec_info, //該指令的其它信息,被打包成一組寬信號,稱之為信息總線(info bus).
 output [`E203_XLEN-1:0] dec_imm, //該指令使用的立即數值。
 output [`E203_PC_SIZE-1:0] dec_pc, // 該指令的pc值,等於輸入的i_pc
 output dec_misalgn, //指令遇到了分支跳轉異常,等於輸入的misalgn
 output dec_buserr,  //指令遭遇了取指存儲器訪問錯誤,等於輸入的i_buserr
 output dec_ilegl, //解碼后,發現該指令是非法指令


 output dec_mulhsu, //指令為 mulh或mulhsu或mulhu,這些乘法指令都把結果的高32位放到目的寄存器
 output dec_mul   , //指令為乘法指令
 output dec_div   , //指令為除法指令
 output dec_rem   ,//指數為取余數指令
 output dec_divu  ,//指令為無符號數除法指令
 output dec_remu  ,//指令為無符號數取余數指令

output dec_rv32, //該指令為32位指令,為0的話則是16位的壓縮指令
 output dec_bjp, //該指令為跳轉指令,jal 或者jalr或者bxx指令
 output dec_jal,  //該指令為jal指令
 output dec_jalr, //該指令為jalr指令
 output dec_bxx, //該指令為bxx

output [`E203_RFIDX_WIDTH-1:0] dec_jalr_rs1idx, //jalr指令中rs1寄存器索引
 output [`E203_XLEN-1:0] dec_bjp_imm  //bjp指令中的立即數

       下面代碼判斷指令是32位指令還是16位指令的代碼。操作碼的低2位11,且3到5位不為111,則為rv32指令,否則為16位指令,因為E203不支持rv64,所以用一位信號就可以表示rv32和rvc了。

wire [32-1:0] rv32_instr = i_instr;
wire [16-1:0] rv16_instr = i_instr[15:0];
//指令的低7位為操作碼
wire [6:0]  opcode = rv32_instr[6:0];

wire opcode_1_0_00  = (opcode[1:0] == 2'b00);
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);
 //為32位指令或者16位指令
 wire rv32 = (~(i_instr[4:2] == 3'b111)) & opcode_1_0_11;


下面代碼為取出32位指令和16位指令的關鍵編碼段。RVC的編碼比較復雜,有些指令寄存器為3位表示,有些為5位表示,立即數通常都有旋轉,旋轉格式還很多。具體參見https://www.cnblogs.com/mikewolf2002/p/9884789.html

wire [4:0]  rv32_rd     = rv32_instr[11:7]; // 目的寄存器索引
 wire [2:0]  rv32_func3  = rv32_instr[14:12];//func3段
 wire [4:0]  rv32_rs1    = rv32_instr[19:15];//源操作數1寄存器索引
 wire [4:0]  rv32_rs2    = rv32_instr[24:20];//源操作數2寄存器索引
 wire [6:0]  rv32_func7  = rv32_instr[31:25];//func7段
 //CR  15-12 func4, 11-7 rd/rs1, 6-2 rs2, 0-1 opcode
 //CI  15-13 func3, 12 imm,11-7 rd/rs1,6-2 imm, 0-1 opcode
 wire [4:0]  rv16_rd     = rv32_rd;
 wire [4:0]  rv16_rs1    = rv16_rd;
 wire [4:0]  rv16_rs2    = rv32_instr[6:2];
 //CIW,CL,CS,CA,CB,CJ
 //rdd=rd', rss1=rs1', rss2=rs2' short register, x8-x15, f8-f15
 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 gatecounts
  wire 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);
   wire rv32_rs2_x0 = (rv32_rs2 == 5'b00000);
   wire 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);
View Code


對32位指令和16位指令進行譯碼

//rv32 load指令,opcode是0000011,不同load指令通過func3區分
wire rv32_load     = opcode_6_5_00 & opcode_4_2_000 & opcode_1_0_11;

//rv32 store指令,opcode是0100011,不同store指令通過func3區分
 wire rv32_store    = opcode_6_5_01 & opcode_4_2_000 & opcode_1_0_11;

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

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

//branch指令opcode=1100011, bxx指令jalr,jal操作碼不同,單獨判斷
 wire rv32_branch   = opcode_6_5_11 & opcode_4_2_000 & opcode_1_0_11;

//浮點數load指令,opcode=0000111,包括fsw,fsd,fsq
//wire rv32_load_fp  = opcode_6_5_00 & opcode_4_2_001 & opcode_1_0_11;

//浮點數store指令,opcode=0100111,包括flw,fld,flq
// wire rv32_store_fp = opcode_6_5_01 & opcode_4_2_001 & opcode_1_0_11;

//msub指令 opcode=1000111,乘減指令
//msub指令是浮點指令的一部分,fmsub.s, fmsub.d, fmsub.q

wire rv32_msub     = opcode_6_5_10 & opcode_4_2_001 & opcode_1_0_11;

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

//opcode為0001011為第一類的定制指令,架構設計者可以實現自己定義的指令
//opcode為0101011為第二類的定制指令,還有第三和第四類的定制指令。

//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;

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

//保留的指令,為了將來擴展用 opcode=1101011
//wire rv32_resved0  = opcode_6_5_11 & opcode_4_2_010 & opcode_1_0_11;

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

wire rv32_miscmem  = opcode_6_5_00 & opcode_4_2_011 & opcode_1_0_11;

//原子指令, opcode=0101111,不同的原子指令,通過func3和func7區分
 `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//}

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

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

//i型的運算指令,opcode=0010011,比如addi

wire rv32_op_imm   = opcode_6_5_00 & opcode_4_2_100 & opcode_1_0_11;

//浮點R型的運算指令, opcode=1010011, 比如add
 wire rv32_op       = opcode_6_5_01 & opcode_4_2_100 & opcode_1_0_11;

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

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

//auipc指令,opcode=0010111

wire rv32_auipc    = opcode_6_5_00 & opcode_4_2_101 & opcode_1_0_11;

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

//第二、三類保留指令
// wire rv32_resved1  = opcode_6_5_10 & opcode_4_2_101 & opcode_1_0_11;
// wire rv32_resved2  = opcode_6_5_11 & opcode_4_2_101 & opcode_1_0_11;

//slliw,srliw,addiw, sraiw等指令的操作碼,opcode=0011011,這些都是64位指令

//wire rv32_op_imm_32= opcode_6_5_00 & opcode_4_2_110 & opcode_1_0_11;

//addw,subw,…等64位算術運算指令
// wire rv32_op_32    = opcode_6_5_01 & opcode_4_2_110 & opcode_1_0_11;

//第三,四類定制指令
// wire rv32_custom2  = opcode_6_5_10 & opcode_4_2_110 & opcode_1_0_11;
// wire rv32_custom3  = opcode_6_5_11 & opcode_4_2_110 & opcode_1_0_11;

//c.addispn, opcode=00, func3=000

wire rv16_addi4spn     = opcode_1_0_00 & rv16_func3_000;

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

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

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

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

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

//c.lui是對的,addi16sp還要判斷11-7位是否是00010
 wire rv16_lui_addi16sp = opcode_1_0_01 & rv16_func3_011;

//一些c.alu指令,比如c.sub等等,opcode=01, func3=100,不同的c.alu指令之間,通過[12-10][6-6]來區分
 wire rv16_miscalu      = opcode_1_0_01 & rv16_func3_100;

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

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

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

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

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

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

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

`ifndef E203_HAS_FPU//{
 wire rv16_flw          = 1'b0;
 wire rv16_fld          = 1'b0;
 wire rv16_fsw          = 1'b0;
 wire rv16_fsd          = 1'b0;
 wire rv16_fldsp        = 1'b0;
 wire rv16_flwsp        = 1'b0;
 wire rv16_fsdsp        = 1'b0;
 wire rv16_fswsp        = 1'b0;
 `endif//}

//對c.lwsp,  rd不能為x0

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

//c.nop指令

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

//一些c.alu指令

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

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

//對壓縮移位指令的合法性判斷

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

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

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

wire rv16_li_lui_ilgl = rv16_li_ilgl | rv16_lui_ilgl;

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

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

wire rv16_jr           = rv16_jalr_mv_add //
                        & (~rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);// The RES rs1=0 illegal is already covered here
 wire rv16_mv           = rv16_jalr_mv_add //
                        & (~rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);
 wire rv16_ebreak       = rv16_jalr_mv_add //
                        & (rv16_instr[12]) & (rv16_rd_x0) & (rv16_rs2_x0);
 wire rv16_jalr         = rv16_jalr_mv_add //
                        & (rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);
 wire rv16_add          = rv16_jalr_mv_add // 
                        & (rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);





 // ===========================================================================
 // Branch Instructions
 wire rv32_beq      = rv32_branch & rv32_func3_000;
 wire rv32_bne      = rv32_branch & rv32_func3_001;
 wire rv32_blt      = rv32_branch & rv32_func3_100;
 wire rv32_bgt      = rv32_branch & rv32_func3_101;
 wire rv32_bltu     = rv32_branch & rv32_func3_110;
 wire rv32_bgtu     = rv32_branch & rv32_func3_111;

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

wire rv32_csrrw    = rv32_system & rv32_func3_001;
 wire rv32_csrrs    = rv32_system & rv32_func3_010;
 wire rv32_csrrc    = rv32_system & rv32_func3_011;
 wire rv32_csrrwi   = rv32_system & rv32_func3_101;
 wire rv32_csrrsi   = rv32_system & rv32_func3_110;
 wire rv32_csrrci   = rv32_system & rv32_func3_111;

wire rv32_dret_ilgl = rv32_dret & (~dbg_mode);

wire rv32_ecall_ebreak_ret_wfi = rv32_system & rv32_func3_000;
 wire rv32_csr          = rv32_system & (~rv32_func3_000);


 // ============================================================
View Code
//c.addispn, opcode=00, func3=000
wire rv16_addi4spn     = opcode_1_0_00 & rv16_func3_000;

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

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

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

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

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

//addi16sp還要判斷11-7位是否是00010
 wire rv16_lui_addi16sp = opcode_1_0_01 & rv16_func3_011;

//一些c.alu指令,比如c.sub等等,opcode=01, func3=100,不同的c.alu指令之間,通過[12-10][6-6]來區分
 wire rv16_miscalu      = opcode_1_0_01 & rv16_func3_100;

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

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

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

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

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

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

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

`ifndef E203_HAS_FPU//{
 wire rv16_flw          = 1'b0;
 wire rv16_fld          = 1'b0;
 wire rv16_fsw          = 1'b0;
 wire rv16_fsd          = 1'b0;
 wire rv16_fldsp        = 1'b0;
 wire rv16_flwsp        = 1'b0;
 wire rv16_fsdsp        = 1'b0;
 wire rv16_fswsp        = 1'b0;
 `endif//}

//對c.lwsp,  rd不能為x0

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

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

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

//一些c.alu指令

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

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

//對壓縮移位指令的合法性判斷

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

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

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

wire rv16_li_lui_ilgl = rv16_li_ilgl | rv16_lui_ilgl;

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

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

wire rv16_jr           = rv16_jalr_mv_add //
                        & (~rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);// The RES rs1=0 illegal is already covered here
 wire rv16_mv           = rv16_jalr_mv_add //
                        & (~rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);
 wire rv16_ebreak       = rv16_jalr_mv_add //
                        & (rv16_instr[12]) & (rv16_rd_x0) & (rv16_rs2_x0);
 wire rv16_jalr         = rv16_jalr_mv_add //
                        & (rv16_instr[12]) & (~rv16_rs1_x0) & (rv16_rs2_x0);
 wire rv16_add          = rv16_jalr_mv_add // 
                        & (rv16_instr[12]) & (~rv16_rd_x0) & (~rv16_rs2_x0);

32位系統指令,csr指令以及分支指令判斷。

 // ===========================================================================
 // Branch Instructions
 wire rv32_beq      = rv32_branch & rv32_func3_000;
 wire rv32_bne      = rv32_branch & rv32_func3_001;
 wire rv32_blt      = rv32_branch & rv32_func3_100;
 wire rv32_bgt      = rv32_branch & rv32_func3_101;
 wire rv32_bltu     = rv32_branch & rv32_func3_110;
 wire rv32_bgtu     = rv32_branch & rv32_func3_111;

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

wire rv32_csrrw    = rv32_system & rv32_func3_001;
 wire rv32_csrrs    = rv32_system & rv32_func3_010;
 wire rv32_csrrc    = rv32_system & rv32_func3_011;
 wire rv32_csrrwi   = rv32_system & rv32_func3_101;
 wire rv32_csrrsi   = rv32_system & rv32_func3_110;
 wire rv32_csrrci   = rv32_system & rv32_func3_111;

//如果為debug模式,則忽視dret不合法的判斷
wire rv32_dret_ilgl = rv32_dret & (~dbg_mode);

wire rv32_ecall_ebreak_ret_wfi = rv32_system & rv32_func3_000;
 wire rv32_csr          = rv32_system & (~rv32_func3_000);


 // ============================================================


      譯碼模塊輸入包括信息總線,信息總線中包含一個3位的grp信息,EXU單元會根據這個grp把解碼后的信號派遣 (dispatch)到該單元進行后續的的處理。E203並不包括EAI和FPU單元,其它5個單元是ALU單元的子單元。不同的指令會在這些子單元中進行后續的執行操作。


image

跳轉和系統指令被BJP單元處理,

下面代碼生成BJP單元所需的信息總線(Info Bus),BJP單元信息總線總共17位。每位表示的意思如下,其中,grp為010:

image

// The Branch and system group of instructions will be handled by BJP

assign dec_jal     = rv32_jal    | rv16_jal  | rv16_j;
 assign dec_jalr    = rv32_jalr   | rv16_jalr | rv16_jr;
 assign dec_bxx     = rv32_branch | rv16_beqz | rv16_bnez;
 assign dec_bjp     = dec_jal | dec_jalr | dec_bxx;


 wire rv32_fence  ;
 wire rv32_fence_i;
 wire rv32_fence_fencei;

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

//生成bjp信息總線信號

wire [`E203_DECINFO_BJP_WIDTH-1:0] bjp_info_bus;
 assign bjp_info_bus[`E203_DECINFO_GRP    ]    = `E203_DECINFO_GRP_BJP;
 assign bjp_info_bus[`E203_DECINFO_RV32   ]    = rv32;
 assign bjp_info_bus[`E203_DECINFO_BJP_JUMP ]  = dec_jal | dec_jalr;
 assign bjp_info_bus[`E203_DECINFO_BJP_BPRDT]  = i_prdt_taken;
 assign bjp_info_bus[`E203_DECINFO_BJP_BEQ  ]  = rv32_beq | rv16_beqz;
 assign bjp_info_bus[`E203_DECINFO_BJP_BNE  ]  = rv32_bne | rv16_bnez;
 assign bjp_info_bus[`E203_DECINFO_BJP_BLT  ]  = rv32_blt;
 assign bjp_info_bus[`E203_DECINFO_BJP_BGT  ]  = rv32_bgt ;
 assign bjp_info_bus[`E203_DECINFO_BJP_BLTU ]  = rv32_bltu;
assign bjp_info_bus[`E203_DECINFO_BJP_BGTU ]  = rv32_bgtu;
 assign bjp_info_bus[`E203_DECINFO_BJP_BXX  ]  = dec_bxx;
 assign bjp_info_bus[`E203_DECINFO_BJP_MRET ]  = rv32_mret;
 assign bjp_info_bus[`E203_DECINFO_BJP_DRET ]  = rv32_dret;
 assign bjp_info_bus[`E203_DECINFO_BJP_FENCE ]  = rv32_fence;
 assign bjp_info_bus[`E203_DECINFO_BJP_FENCEI]  = rv32_fence_i;


















免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM