RISCV 模拟器中指令解析部分的实现代码



unsigned int get_ins_func7_b(unsigned int i){ 
unsigned int r,mask ;
mask = (1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25);
r = mask & i ;  return r;
}
	
unsigned int get_ins_func3_b(unsigned int i){
unsigned int r,mask ;
mask=0;
mask = (1<<14)|(1<<13)|(1<<12);
r = mask & i  ;  return r;	
}

unsigned int get_ins_opcode_b(unsigned int i ){
unsigned int r,mask ;
mask = (1<<2) | (1<<3)| (1<<4) | (1<<5) | (1<<6);
r = mask & i ;  return r;
} 

unsigned int get_ins_func7_s(const unsigned char *p){
unsigned int r=0;
if (p[4]=='x')return -1;
    r=0;  if (p[4]=='1')r=1;
r<<=1;if (p[5]=='1')r|=1;
r<<=1;if (p[6]=='1')r|=1;
r<<=1;if (p[7]=='1')r|=1;
r<<=1;if (p[8]=='1')r|=1;
r<<=1;if (p[9]=='1')r|=1;
r<<=1;if (p[10]=='1')r|=1;
r<<=25;		
//printf("                              func7 result is %08x\n",r);
return r ;
}
	
unsigned int get_ins_func3_s(const unsigned char *p){
	
unsigned int r=0;
if (p[12]=='x')return -1;
r=0  ;if (p[12]=='1')r|=1;
r<<=1;if (p[13]=='1')r|=1;
r<<=1;if (p[14]=='1')r|=1;
r<<=12;
return r;
}

unsigned int get_ins_opcode_s(const unsigned char *p){
unsigned int r=0;
if (p[16]=='x')return -1;
r=0  ;if (p[16]=='1')r|=1;
r<<=1;if (p[17]=='1')r|=1;
r<<=1;if (p[18]=='1')r|=1;
r<<=1;if (p[19]=='1')r|=1;
r<<=1;if (p[20]=='1')r|=1;
r<<=2;
return r;
}

unsigned int get_bits(unsigned int v,unsigned int left,unsigned int right){
         int i ;
         unsigned int r = 0 ;    
         for(i=left;i>=right;i--){
         r<<=1;  
         if ( v &(1<<i)) r|=1;
         } 
         return r;
}

		

int cmp_ins(unsigned int src_ins,const char*dst_ins)
{
    int r ;
    unsigned int src_opcode,src_func3,src_func7 ;
    unsigned int dst_opcode,dst_func3,dst_func7 ;
    dst_opcode=get_ins_opcode_s(dst_ins);
    dst_func3=get_ins_func3_s(dst_ins);
    dst_func7=get_ins_func7_s(dst_ins);
    src_opcode=get_ins_opcode_b(src_ins);
    src_func3=get_ins_func3_b(src_ins);
    src_func7=get_ins_func7_b(src_ins);
    if((dst_opcode!=-1)&&(dst_opcode!=src_opcode))return 0 ;
    if((dst_func3!=-1)&&(dst_func3!=src_func3))return 0 ;
    if((dst_func7!=-1)&&(dst_func7!=src_func7))return 0 ;
    return 1 ;
}

//                          func7_func3_opcode  
#define      LUI       "15'bxxxxxxx_xxx_01101"
#define      AUIPC     "15'bxxxxxxx_xxx_00101"
#define      JAL       "15'bxxxxxxx_xxx_11011"
#define      JALR      "15'bxxxxxxx_000_11001"
#define      BEQ       "15'bxxxxxxx_000_11000"
#define      BNE       "15'bxxxxxxx_001_11000"
#define      BLT       "15'bxxxxxxx_100_11000"
#define      BGE       "15'bxxxxxxx_101_11000"
#define      BLTU      "15'bxxxxxxx_110_11000"
#define      BGEU      "15'bxxxxxxx_111_11000"

#define      LB        "15'bxxxxxxx_000_00000"
#define      LH        "15'bxxxxxxx_001_00000"
#define      LW        "15'bxxxxxxx_010_00000"
#define      LBU       "15'bxxxxxxx_100_00000"
#define      LHU       "15'bxxxxxxx_101_00000"
#define      LWU       "15'bxxxxxxx_110_00000"
#define      LD        "15'bxxxxxxx_011_00000"

#define      SB        "15'bxxxxxxx_000_01000"
#define      SH        "15'bxxxxxxx_001_01000"
#define      SW        "15'bxxxxxxx_010_01000"
#define      SD        "15'bxxxxxxx_011_01000"

#define      ADDI      "15'bxxxxxxx_000_00100"
#define      ADDIW     "15'bxxxxxxx_000_00110"
#define      ADD       "15'b0000000_000_01100"
#define      ADDW      "15'b0000000_000_01110"
#define      SUB       "15'b0100000_000_01100"
#define      SUBW      "15'b0100000_000_01110"
#define      XORI      "15'bxxxxxxx_100_00100"
#define      XOR       "15'b0000000_100_01100"
#define      ORI       "15'bxxxxxxx_110_00100"
#define      OR        "15'b0000000_110_01100"
#define      ANDI      "15'bxxxxxxx_111_00100"
#define      AND       "15'b0000000_111_01100"
#define      SLLI      "15'b0000000_001_00100"
//#define      SLLI      "15'b000000?_001_00100"
#define      SLLIW     "15'b0000001_001_00110"
#define      SLL       "15'b0000000_001_01100"
#define      SLLW      "15'b0000000_001_01110"
#define      SLTI      "15'bxxxxxxx_010_00100"
#define      SLT       "15'b0000000_010_01100"
#define      SLTU      "15'b0000000_011_01100"
#define      SLTIU     "15'bxxxxxxx_011_00100"
#define      SRLI      "15'b0000000_101_00100"
//#define      SRLI      "15'b000000?_101_00100"
#define      SRLIW     "15'b0000000_101_00110"
#define      SRL       "15'b0000000_101_01100"
#define      SRLW      "15'b0000000_101_01110"
#define      SRAI      "15'b0100000_101_00100"
//#define      SRAI      "15'b010000?_101_00100"
#define      SRAIW     "15'b0100000_101_00110"
#define      SRA       "15'b0100000_101_01100"
#define      SRAW      "15'b0100000_101_01110"
 

使用时候调用如下:

     if (cmp_ins (INS, LUI )) { if (debug())printf("LUI ");   ALU_RES =  (IMM_U << 12);  ALU_RES = IMM_U;ALU_RES<<=12; PC=PC+4; st= EXE_WR_TYPE_2REG ; }
else if (cmp_ins (INS, AUIPC )) { if (debug())printf("AUIPC ");   ALU_RES =PC+  (IMM_U << 12);  PC=PC+4; st=EXE_WR_TYPE_2REG;  }
else if (cmp_ins (INS, JAL   )) { if (debug())printf("JAL ");   ALU_RES = PC + 4 ;     PC=PC+ext_s( IMM_UJ,20);  st = EXE_WR_TYPE_2REG ;}
else if (cmp_ins (INS, JALR  )) { if (debug())printf("JALR ");  ALU_RES = PC + 4 ;     PC =RS1_VAL + ext_s(IMM_I,11) ; st = EXE_WR_TYPE_2REG ; }

就实现了解码。

这里这些#define文件是从一个开源的riscv实现里面拷贝出来做简单修改后得到的。这部分预定也可以简单去掉"号,直接在verilog代码里面用case 使用。这里注意opcode省略了底2位的2‘b’11

//                        func7_func3_opcode
`define      LUI        15'bxxxxxxx_xxx_01101 
`define      AUIPC      15'bxxxxxxx_xxx_00101 
`define      JAL        15'bxxxxxxx_xxx_11011 
`define      JALR       15'bxxxxxxx_000_11001 
`define      BEQ        15'bxxxxxxx_000_11000 
`define      BNE        15'bxxxxxxx_001_11000 
`define      BLT        15'bxxxxxxx_100_11000 
`define      BGE        15'bxxxxxxx_101_11000 
`define      BLTU       15'bxxxxxxx_110_11000 
`define      BGEU       15'bxxxxxxx_111_11000 
`define      LB         15'bxxxxxxx_000_00000 
`define      LH         15'bxxxxxxx_001_00000 
`define      LW         15'bxxxxxxx_010_00000 
`define      LBU        15'bxxxxxxx_100_00000 
`define      LHU        15'bxxxxxxx_101_00000 
`define      LWU        15'bxxxxxxx_110_00000 
`define      LD         15'bxxxxxxx_011_00000 
`define      SB         15'bxxxxxxx_000_01000 
`define      SH         15'bxxxxxxx_001_01000 
`define      SW         15'bxxxxxxx_010_01000 
`define      SD         15'bxxxxxxx_011_01000 
`define      ADDI       15'bxxxxxxx_000_00100 
`define      ADDIW      15'bxxxxxxx_000_00110 
`define      ADD        15'b0000000_000_01100 
`define      ADDW       15'b0000000_000_01110 
`define      SUB        15'b0100000_000_01100 
`define      SUBW       15'b0100000_000_01110 
`define      XORI       15'bxxxxxxx_100_00100 
`define      XOR        15'b0000000_100_01100 
`define      ORI        15'bxxxxxxx_110_00100 
`define      OR         15'b0000000_110_01100 
`define      ANDI       15'bxxxxxxx_111_00100 
`define      AND        15'b0000000_111_01100 
`define      SLLI       15'b0000000_001_00100 
`define      SLLIW      15'b0000001_001_00110 
`define      SLL        15'b0000000_001_01100 
`define      SLLW       15'b0000000_001_01110 
`define      SLTI       15'bxxxxxxx_010_00100 
`define      SLT        15'b0000000_010_01100 
`define      SLTU       15'b0000000_011_01100 
`define      SLTIU      15'bxxxxxxx_011_00100 
`define      SRLI       15'b0000000_101_00100 
`define      SRLIW      15'b0000000_101_00110 
`define      SRL        15'b0000000_101_01100 
`define      SRLW       15'b0000000_101_01110  
`define      SRAI       15'b0100000_101_00100 
`define      SRAIW      15'b0100000_101_00110 
`define      SRA        15'b0100000_101_01100 
`define      SRAW       15'b0100000_101_01110  
`define      SRLI       15'b0000000_101_00100 
`define      SLLI       15'b0000000_001_00100 






    always @ (posedge clk)if(rst)st<=ST_IDLE;else
    case (st)
        ST_IDLE : st<= WB_NOP  ;
        ST_RF_ID : st<=ST_EX;
        ST_EX : casex ({INS[31:25],INS[14:12],INS[6:2]})
            `ADDI,
            `ADD,
            `SUB,
            `XORI,`XOR,`ORI,`OR,`ANDI,`AND,
            `LUI,`AUIPC,`JAL,`JALR :st<=WB_2REG;

 

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值