import "RISCVBase.core_desc" InsructionSet RV32M extends RISCVBase { constants { MAXLEN:=128 } instructions{ MUL{ encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); X[rd]<= zext(res , XLEN); } } MULH { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= sext(X[rs1], MAXLEN) * sext(X[rs2], MAXLEN); X[rd]<= zext(res >> XLEN, XLEN); } } MULHSU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= sext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); X[rd]<= zext(res >> XLEN, XLEN); } } MULHU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); X[rd]<= zext(res >> XLEN, XLEN); } } DIV { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0){ val M1[XLEN] <= -1; val XLM1[8] <= XLEN-1; val ONE[XLEN] <= 1; val MMIN[XLEN] <= ONE<<XLM1; if(X[rs1]==MMIN && X[rs2]==M1) X[rd] <= MMIN; else X[rd] <= X[rs1]s / X[rs2]s; }else X[rd] <= -1; } } DIVU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) X[rd] <= X[rs1] / X[rs2]; else X[rd] <= -1; } } REM { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) { val M1[XLEN] <= -1; // constant -1 val XLM1[32] <= XLEN-1; val ONE[XLEN] <= 1; val MMIN[XLEN] <= ONE<<XLM1; // -2^(XLEN-1) if(X[rs1]==MMIN && X[rs2]==M1) X[rd] <= 0; else X[rd] <= X[rs1]'s % X[rs2]'s; } else X[rd] <= X[rs1]; } } REMU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) X[rd] <= X[rs1] % X[rs2]; else X[rd] <= X[rs1]; } } } } InsructionSet RV64M extends RV32M { instructions{ MULW{ encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ X[rd]<= sext(X[rs1]{32} * X[rs2]{32}); } } DIVW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0){ val M1[32] <= -1; val ONE[32] <= 1; val MMIN[32] <= ONE<<31; if(X[rs1]{32}==MMIN && X[rs2]{32}==M1) X[rd] <= -1<<31; else X[rd] <= sext(X[rs1]{32}s / X[rs2]{32}s); }else X[rd] <= -1; } } DIVUW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]{32}!=0) X[rd] <= sext(X[rs1]{32} / X[rs2]{32}); else X[rd] <= -1; } } REMW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) { val M1[32] <= -1; // constant -1 val ONE[32] <= 1; val MMIN[32] <= ONE<<31; // -2^(XLEN-1) if(X[rs1]{32}==MMIN && X[rs2]==M1) X[rd] <= 0; else X[rd] <= sext(X[rs1]{32}s % X[rs2]{32}s); } else X[rd] <= sext(X[rs1]{32}); } } REMUW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]{32}!=0) X[rd] <= sext(X[rs1]{32} % X[rs2]{32}); else X[rd] <= sext(X[rs1]{32}); } } } }