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