import "RISCVBase.core_desc" InsructionSet RV32IC extends RISCVBase{ instructions{ JALR(no_cont){ // overwriting the implementation if rv32i, alignment does not need to be word encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; args_disass: "{name(rd)}, {name(rs1)}, {imm:#0x}"; val new_pc[XLEN] <= X[rs1]s + imm; if(rd!=0) X[rd] <= PC+4; PC<=new_pc & ~0x1; } C.ADDI4SPN { //(RES, imm=0) encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00; args_disass: "{name(rd)}, {imm:#05x}"; if(imm == 0) raise(0, 2); X[rd+8] <= X[2] + imm; } C.LW { // (RV32) encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; args_disass: "{name(8+rd)}, {uimm:#05x}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; X[rd+8] <= sext(MEM[offs]{32}); } C.SW {//(RV32) encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; args_disass: "{name(8+rs2)}, {uimm:#05x}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; MEM[offs]{32} <= X[rs2+8]; } C.ADDI {//(RV32) encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01; args_disass: "{name(rs1)}, {imm:#05x}"; X[rs1] <= X[rs1]'s + imm; } C.NOP { encoding:b000 | b0 | b00000 | b00000 | b01; } // C.JAL will be overwritten by C.ADDIW for RV64/128 C.JAL(no_cont) {//(RV32) encoding: b001 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; args_disass: "{imm:#05x}"; X[1] <= PC+2; PC<=PC's+imm; } C.LI {//(RV32) encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01; args_disass: "{name(rd)}, {imm:#05x}"; if(rd == 0) raise(0, 2); //TODO: should it be handled as trap? X[rd] <= imm; } // order matters here as C.ADDI16SP overwrites C.LUI vor rd==2 C.LUI {//(RV32) encoding:b011 | imm[17:17] | rd[4:0] | imm[16:12]s | b01; args_disass: "{name(rd)}, {imm:#05x}"; if(rd == 0) raise(0, 2); //TODO: should it be handled as trap? if(imm == 0) raise(0, 2); //TODO: should it be handled as trap? X[rd] <= imm; } C.ADDI16SP {//(RV32) encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01; args_disass: "{imm:#05x}"; X[2] <= X[2]s + imm; } C.SRLI {//(RV32 nse) encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01; args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shrl(X[rs1_idx], shamt); } C.SRAI {//(RV32) encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01; args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shra(X[rs1_idx], shamt); } C.ANDI {//(RV32) encoding:b100 | imm[5:5]s | b10 | rs1[2:0] | imm[4:0]s | b01; args_disass: "{name(8+rs1)}, {imm:#05x}"; val rs1_idx[5] <= rs1 + 8; X[rs1_idx] <= X[rs1_idx]s & imm; } C.SUB {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] - X[rs2 + 8]; } C.XOR {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] ^ X[rs2 + 8]; } C.OR {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b10 | rs2[2:0] | b01; args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] | X[rs2 + 8]; } C.AND {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b11 | rs2[2:0] | b01; args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] & X[rs2 + 8]; } C.J(no_cont) {//(RV32) encoding:b101 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; args_disass: "{imm:#05x}"; PC<=PC's+imm; } C.BEQZ(no_cont,cond) {//(RV32) encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01; args_disass: "{name(8+rs1)}, {imm:#05x}"; PC<=choose(X[rs1+8]==0, PC's+imm, PC+2); } C.BNEZ(no_cont,cond) {//(RV32) encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01; args_disass: "{name(8+rs1)}, {imm:#05x}"; PC<=choose(X[rs1+8]!=0, PC's+imm, PC+2); } C.SLLI {//(RV32) encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10; args_disass: "{name(rs1)}, {shamt}"; if(rs1 == 0) raise(0, 2); X[rs1] <= shll(X[rs1], shamt); } C.LWSP {// encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; args_disass: "{name(rd)}, sp, {uimm:#05x}"; val offs[XLEN] <= X[2] + uimm; X[rd] <= sext(MEM[offs]{32}); } // order matters as C.JR is a special case of C.MV C.MV {//(RV32) encoding:b100 | b0 | rd[4:0] | rs2[4:0] | b10; args_disass: "{name(rd)}, {name(rs2)}"; X[rd] <= X[rs2]; } C.JR(no_cont) {//(RV32) encoding:b100 | b0 | rs1[4:0] | b00000 | b10; args_disass: "{name(rs1)}"; PC <= X[rs1]; } // order matters as C.EBREAK is a special case of C.JALR which is a special case of C.ADD C.ADD {//(RV32) encoding:b100 | b1 | rd[4:0] | rs2[4:0] | b10; args_disass: "{name(rd)}, {name(rs2)}"; X[rd] <= X[rd] + X[rs2]; } C.JALR(no_cont) {//(RV32) encoding:b100 | b1 | rs1[4:0] | b00000 | b10; args_disass: "{name(rs1)}"; X[1] <= PC+2; PC<=X[rs1]; } C.EBREAK(no_cont) {//(RV32) encoding:b100 | b1 | b00000 | b00000 | b10; raise(0, 3); } C.SWSP {// encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; args_disass: "{name(rs2)}, {uimm:#05x}(sp)"; val offs[XLEN] <= X[2] + uimm; MEM[offs]{32} <= X[rs2]; } DII { encoding:b000 | b0 | b00000 | b00000 | b00; raise(0, 2); } } } InsructionSet RV32FC extends RV32IC{ constants { FLEN } registers { [31:0] F[FLEN] } instructions{ C.FLW { encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; args_disass:"f(8+{rd}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; val res[32] <= MEM[offs]{32}; if(FLEN==32) F[rd+8] <= res; else { // NaN boxing val upper[FLEN] <= -1; F[rd+8] <= (upper<<32) | zext(res, FLEN); } } C.FSW { encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; args_disass:"f(8+{rs2}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; MEM[offs]{32}<=F[rs2+8]{32}; } C.FLWSP { encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; args_disass:"f{rd}, {uimm}(x2)"; val offs[XLEN] <= X[2]+uimm; val res[32] <= MEM[offs]{32}; if(FLEN==32) F[rd] <= res; else { // NaN boxing val upper[FLEN] <= -1; F[rd] <= (upper<<32) | zext(res, FLEN); } } C.FSWSP { encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; args_disass:"f{rs2}, {uimm}(x2), "; val offs[XLEN] <= X[2]+uimm; MEM[offs]{32}<=F[rs2]{32}; } } } InsructionSet RV32DC extends RV32IC{ constants { FLEN } registers { [31:0] F[FLEN] } instructions{ C.FLD { //(RV32/64) encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; args_disass:"f(8+{rd}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; val res[64] <= MEM[offs]{64}; if(FLEN==64) F[rd+8] <= res; else { // NaN boxing val upper[FLEN] <= -1; F[rd+8] <= (upper<<64) | res; } } C.FSD { //(RV32/64) encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; args_disass:"f(8+{rs2}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; MEM[offs]{64}<=F[rs2+8]{64}; } C.FLDSP {//(RV32/64) encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; args_disass:"f{rd}, {uimm}(x2)"; val offs[XLEN] <= X[2]+uimm; val res[64] <= MEM[offs]{64}; if(FLEN==64) F[rd] <= res; else { // NaN boxing val upper[FLEN] <= -1; F[rd] <= (upper<<64) | zext(res, FLEN); } } C.FSDSP {//(RV32/64) encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; args_disass:"f{rs2}, {uimm}(x2), "; val offs[XLEN] <= X[2]+uimm; MEM[offs]{64}<=F[rs2]{64}; } } } InsructionSet RV64IC extends RV32IC { instructions{ C.LD {//(RV64/128) encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; args_disass: "{name(8+rd)}, {uimm},({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8] + uimm; X[rd+8]<=sext(MEM[offs]{64}); } C.SD { //(RV64/128) encoding:b111 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; args_disass: "{name(8+rs2)}, {uimm},({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8] + uimm; MEM[offs]{64} <= X[rs2+8]; } C.SUBW {//(RV64/128, RV32 res) encoding:b100 | b1 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; args_disass: "{name(8+rd)}, {name(8+rd)}, {name(8+rs2)}"; val res[32] <= X[rd+8]{32} - X[rs2+8]{32}; X[rd+8] <= sext(res); } C.ADDW {//(RV64/128 RV32 res) encoding:b100 | b1 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; args_disass: "{name(8+rd)}, {name(8+rd)}, {name(8+rs2)}"; val res[32] <= X[rd+8]{32} + X[rs2+8]{32}; X[rd+8] <= sext(res); } C.ADDIW {//(RV64/128) encoding:b001 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01; args_disass: "{name(rs1)}, {imm:#05x}"; if(rs1 != 0){ val res[32] <= X[rs1]{32}'s + imm; X[rs1] <= sext(res); } } C.SRLI {//(RV64) encoding:b100 | shamt[5:5] | b00 | rs1[2:0] | shamt[4:0] | b01; args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shrl(X[rs1_idx], shamt); } C.SRAI {//(RV64) encoding:b100 | shamt[5:5] | b01 | rs1[2:0] | shamt[4:0] | b01; args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shra(X[rs1_idx], shamt); } C.SLLI {//(RV64) encoding:b000 | shamt[5:5] | rs1[4:0] | shamt[4:0] | b10; args_disass: "{name(rs1)}, {shamt}"; if(rs1 == 0) raise(0, 2); X[rs1] <= shll(X[rs1], shamt); } C.LDSP {//(RV64/128 encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; args_disass:"{name(rd)}, {uimm}(sp)"; val offs[XLEN] <= X[2] + uimm; if(rd!=0) X[rd]<=sext(MEM[offs]{64}); } C.SDSP {//(RV64/128) encoding:b111 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; args_disass:"{name(rs2)}, {uimm}(sp)"; val offs[XLEN] <= X[2] + uimm; MEM[offs]{64} <= X[rs2]; } } } InsructionSet RV128IC extends RV64IC { instructions{ C.SRLI {//(RV128) encoding:b100 | shamt[5:5] | b00 | rs1[2:0] | shamt[4:0] | b01; args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shrl(X[rs1_idx], shamt); } C.SRAI {//(RV128) encoding:b100 | shamt[5:5] | b01 | rs1[2:0] | shamt[4:0] | b01; args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shra(X[rs1_idx], shamt); } C.SLLI {//(RV128) encoding:b000 | shamt[5:5] | rs1[4:0] | shamt[4:0] | b10; args_disass: "{name(rs1)}, {shamt}"; if(rs1 == 0) raise(0, 2); X[rs1] <= shll(X[rs1], shamt); } C.LQ { //(RV128) encoding:b001 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; } C.SQ { //(RV128) encoding:b101 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; } C.SQSP {//(RV128) encoding:b101 | uimm[5:4] | uimm[9:6] | rs2[4:0] | b10; } } }