move CoreDSL instraction set description files into a dedicated repository CoreDSL-Instruction-Set-Description

This commit is contained in:
Stanislaw Kaushanski 2020-08-21 15:57:01 +02:00
parent 8fce0c4759
commit 03172e352d
10 changed files with 4 additions and 1978 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "gen_input/CoreDSL-Instruction-Set-Description"]
path = gen_input/CoreDSL-Instruction-Set-Description
url = https://git.minres.com/DBT-RISE/CoreDSL-Instruction-Set-Description.git

@ -0,0 +1 @@
Subproject commit 3bb3763e9277642333b42f0f5bd4bd15c1546bb7

View File

@ -1,50 +0,0 @@
InsructionSet RISCVBase {
constants {
XLEN,
fence:=0,
fencei:=1,
fencevmal:=2,
fencevmau:=3
}
address_spaces {
MEM[8], CSR[XLEN], FENCE[XLEN], RES[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc),
alias ZERO[XLEN] is X[0],
alias RA[XLEN] is X[1],
alias SP[XLEN] is X[2],
alias GP[XLEN] is X[3],
alias TP[XLEN] is X[4],
alias T0[XLEN] is X[5],
alias T1[XLEN] is X[6],
alias T2[XLEN] is X[7],
alias S0[XLEN] is X[8],
alias S1[XLEN] is X[9],
alias A0[XLEN] is X[10],
alias A1[XLEN] is X[11],
alias A2[XLEN] is X[12],
alias A3[XLEN] is X[13],
alias A4[XLEN] is X[14],
alias A5[XLEN] is X[15],
alias A6[XLEN] is X[16],
alias A7[XLEN] is X[17],
alias S2[XLEN] is X[18],
alias S3[XLEN] is X[19],
alias S4[XLEN] is X[20],
alias S5[XLEN] is X[21],
alias S6[XLEN] is X[22],
alias S7[XLEN] is X[23],
alias S8[XLEN] is X[24],
alias S9[XLEN] is X[25],
alias S10[XLEN] is X[26],
alias S11[XLEN] is X[27],
alias T3[XLEN] is X[28],
alias T4[XLEN] is X[29],
alias T5[XLEN] is X[30],
alias T6[XLEN] is X[31]
}
}

View File

@ -1,309 +0,0 @@
import "RISCVBase.core_desc"
InsructionSet RV32I extends RISCVBase{
instructions {
LUI{
encoding: imm[31:12]s | rd[4:0] | b0110111;
args_disass: "{name(rd)}, {imm:#05x}";
if(rd!=0) X[rd] <= imm;
}
AUIPC{
encoding: imm[31:12]s | rd[4:0] | b0010111;
args_disass: "{name(rd)}, {imm:#08x}";
if(rd!=0) X[rd] <= PC's+imm;
}
JAL(no_cont){
encoding: imm[20:20]s | imm[10:1]s | imm[11:11]s | imm[19:12]s | rd[4:0] | b1101111;
args_disass: "{name(rd)}, {imm:#0x}";
if(rd!=0) X[rd] <= PC+4;
PC<=PC's+imm;
}
JALR(no_cont){
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;
val align[XLEN] <= new_pc & 0x2;
if(align != 0){
raise(0, 0);
} else {
if(rd!=0) X[rd] <= PC+4;
PC<=new_pc & ~0x1;
}
}
BEQ(no_cont,cond){
encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:1]s | imm[11:11]s | b1100011;
args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}";
PC<=choose(X[rs1]==X[rs2], PC's+imm, PC+4);
}
BNE(no_cont,cond){
encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:1]s | imm[11:11]s | b1100011;
args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}";
PC<=choose(X[rs1]!=X[rs2], PC's+imm, PC+4);
}
BLT(no_cont,cond){
encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b100 | imm[4:1]s | imm[11:11]s | b1100011;
args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}";
PC<=choose(X[rs1]s<X[rs2]s, PC's+imm, PC+4);
}
BGE(no_cont,cond) {
encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b101 | imm[4:1]s | imm[11:11]s | b1100011;
args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}";
PC<=choose(X[rs1]s>=X[rs2]s, PC's+imm, PC+4);
}
BLTU(no_cont,cond) {
encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b110 | imm[4:1]s | imm[11:11]s | b1100011;
args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}";
PC<=choose(X[rs1]<X[rs2],PC's+imm, PC+4);
}
BGEU(no_cont,cond) {
encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b111 | imm[4:1]s | imm[11:11]s | b1100011;
args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}";
PC<=choose(X[rs1]>=X[rs2], PC's+imm, PC+4);
}
LB {
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s+imm;
if(rd!=0) X[rd]<=sext(MEM[offs]);
}
LH {
encoding: imm[11:0]s | rs1[4:0] | b001 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s+imm;
if(rd!=0) X[rd]<=sext(MEM[offs]{16});
}
LW {
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s+imm;
if(rd!=0) X[rd]<=sext(MEM[offs]{32});
}
LBU {
encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s+imm;
if(rd!=0) X[rd]<=zext(MEM[offs]);
}
LHU {
encoding: imm[11:0]s | rs1[4:0] | b101 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s+imm;
if(rd!=0) X[rd]<=zext(MEM[offs]{16});
}
SB {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:0]s | b0100011;
args_disass:"{name(rs2)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
MEM[offs] <= X[rs2];
}
SH {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:0]s | b0100011;
args_disass:"{name(rs2)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
MEM[offs]{16} <= X[rs2];
}
SW {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100011;
args_disass:"{name(rs2)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
MEM[offs]{32} <= X[rs2];
}
ADDI {
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
if(rd != 0) X[rd] <= X[rs1]'s + imm;
}
SLTI {
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
if (rd != 0) X[rd] <= choose(X[rs1]s < imm's, 1, 0);
}
SLTIU {
encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
val full_imm[XLEN] <= imm's;
if (rd != 0) X[rd] <= choose(X[rs1]'u < full_imm'u, 1, 0);
}
XORI {
encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
if(rd != 0) X[rd] <= X[rs1]s ^ imm;
}
ORI {
encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
if(rd != 0) X[rd] <= X[rs1]s | imm;
}
ANDI {
encoding: imm[11:0]s | rs1[4:0] | b111 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
if(rd != 0) X[rd] <= X[rs1]s & imm;
}
SLLI {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(shamt > 31){
raise(0,0);
} else {
if(rd != 0) X[rd] <= shll(X[rs1], shamt);
}
}
SRLI {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(shamt > 31){
raise(0,0);
} else {
if(rd != 0) X[rd] <= shrl(X[rs1], shamt);
}
}
SRAI {
encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(shamt > 31){
raise(0,0);
} else {
if(rd != 0) X[rd] <= shra(X[rs1], shamt);
}
}
ADD {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= X[rs1] + X[rs2];
}
SUB {
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= X[rs1] - X[rs2];
}
SLL {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&(XLEN-1));
}
SLT {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if (rd != 0) X[rd] <= choose(X[rs1]s < X[rs2]s, 1, 0);
}
SLTU {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if (rd != 0) X[rd] <= choose(zext(X[rs1]) < zext(X[rs2]), 1, 0);
}
XOR {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= X[rs1] ^ X[rs2];
}
SRL {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&(XLEN-1));
}
SRA {
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&(XLEN-1));
}
OR {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= X[rs1] | X[rs2];
}
AND {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0) X[rd] <= X[rs1] & X[rs2];
}
FENCE {
encoding: b0000 | pred[3:0] | succ[3:0] | rs1[4:0] | b000 | rd[4:0] | b0001111;
FENCE[fence] <= pred<<4 | succ;
}
FENCE_I(flush) {
encoding: imm[11:0] | rs1[4:0] | b001 | rd[4:0] | b0001111 ;
FENCE[fencei] <= imm;
}
ECALL(no_cont) {
encoding: b000000000000 | b00000 | b000 | b00000 | b1110011;
raise(0, 11);
}
EBREAK(no_cont) {
encoding: b000000000001 | b00000 | b000 | b00000 | b1110011;
raise(0, 3);
}
URET(no_cont) {
encoding: b0000000 | b00010 | b00000 | b000 | b00000 | b1110011;
leave(0);
}
SRET(no_cont) {
encoding: b0001000 | b00010 | b00000 | b000 | b00000 | b1110011;
leave(1);
}
MRET(no_cont) {
encoding: b0011000 | b00010 | b00000 | b000 | b00000 | b1110011;
leave(3);
}
WFI {
encoding: b0001000 | b00101 | b00000 | b000 | b00000 | b1110011;
wait(1);
}
SFENCE.VMA {
encoding: b0001001 | rs2[4:0] | rs1[4:0] | b000 | b00000 | b1110011;
FENCE[fencevmal] <= rs1;
FENCE[fencevmau] <= rs2;
}
CSRRW {
encoding: csr[11:0] | rs1[4:0] | b001 | rd[4:0] | b1110011;
args_disass:"{name(rd)}, {csr}, {name(rs1)}";
val rs_val[XLEN] <= X[rs1];
if(rd!=0){
val csr_val[XLEN] <= CSR[csr];
CSR[csr] <= rs_val;
// make sure Xrd is updated once CSR write succeeds
X[rd] <= csr_val;
} else {
CSR[csr] <= rs_val;
}
}
CSRRS {
encoding: csr[11:0] | rs1[4:0] | b010 | rd[4:0] | b1110011;
args_disass:"{name(rd)}, {csr}, {name(rs1)}";
val xrd[XLEN] <= CSR[csr];
val xrs1[XLEN] <= X[rs1];
if(rd!=0) X[rd] <= xrd;
if(rs1!=0) CSR[csr] <= xrd | xrs1;
}
CSRRC {
encoding: csr[11:0] | rs1[4:0] | b011 | rd[4:0] | b1110011;
args_disass:"{name(rd)}, {csr}, {name(rs1)}";
val xrd[XLEN] <= CSR[csr];
val xrs1[XLEN] <= X[rs1];
if(rd!=0) X[rd] <= xrd;
if(rs1!=0) CSR[csr] <= xrd & ~xrs1;
}
CSRRWI {
encoding: csr[11:0] | zimm[4:0] | b101 | rd[4:0] | b1110011;
args_disass:"{name(rd)}, {csr}, {zimm:#0x}";
if(rd!=0) X[rd] <= CSR[csr];
CSR[csr] <= zext(zimm);
}
CSRRSI {
encoding: csr[11:0] | zimm[4:0] | b110 | rd[4:0] | b1110011;
args_disass:"{name(rd)}, {csr}, {zimm:#0x}";
val res[XLEN] <= CSR[csr];
if(zimm!=0) CSR[csr] <= res | zext(zimm);
// make sure rd is written after csr write succeeds
if(rd!=0) X[rd] <= res;
}
CSRRCI {
encoding: csr[11:0] | zimm[4:0] | b111 | rd[4:0] | b1110011;
args_disass:"{name(rd)}, {csr}, {zimm:#0x}";
val res[XLEN] <= CSR[csr];
if(rd!=0) X[rd] <= res;
if(zimm!=0) CSR[csr] <= res & ~zext(zimm, XLEN);
}
}
}

View File

@ -1,116 +0,0 @@
import "RV32I.core_desc"
InsructionSet RV64I extends RV32I {
instructions{
LWU { // 80000104: 0000ef03 lwu t5,0(ra)
encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s+imm;
if(rd!=0) X[rd]<=zext(MEM[offs]{32});
}
LD{
encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000011;
args_disass:"{name(rd)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
if(rd!=0) X[rd]<=sext(MEM[offs]{64});
}
SD{
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100011;
args_disass:"{name(rs2)}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
MEM[offs]{64} <= X[rs2];
}
SLLI {
encoding: b000000 | shamt[5:0] | rs1[4:0] | b001 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(rd != 0) X[rd] <= shll(X[rs1], shamt);
}
SRLI {
encoding: b000000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(rd != 0) X[rd] <= shrl(X[rs1], shamt);
}
SRAI {
encoding: b010000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(rd != 0) X[rd] <= shra(X[rs1], shamt);
}
ADDIW {
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011;
args_disass:"{name(rd)}, {name(rs1)}, {imm}";
if(rd != 0){
val res[32] <= X[rs1]{32}'s + imm;
X[rd] <= sext(res);
}
}
SLLIW {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(rd != 0){
val sh_val[32] <= shll(X[rs1]{32}, shamt);
X[rd] <= sext(sh_val);
}
}
SRLIW {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(rd != 0){
val sh_val[32] <= shrl(X[rs1]{32}, shamt);
X[rd] <= sext(sh_val);
}
}
SRAIW {
encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
args_disass:"{name(rd)}, {name(rs1)}, {shamt}";
if(rd != 0){
val sh_val[32] <= shra(X[rs1]{32}, shamt);
X[rd] <= sext(sh_val);
}
}
ADDW {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011;
if(rd != 0){
val res[32] <= X[rs1]{32} + X[rs2]{32};
X[rd] <= sext(res);
}
}
SUBW {
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011;
if(rd != 0){
val res[32] <= X[rs1]{32} - X[rs2]{32};
X[rd] <= sext(res);
}
}
SLLW {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0){
val mask[32] <= 0x1f;
val count[32] <= X[rs2]{32} & mask;
val sh_val[32] <= shll(X[rs1]{32}, count);
X[rd] <= sext(sh_val);
}
}
SRLW {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0){
val mask[32] <= 0x1f;
val count[32] <= X[rs2]{32} & mask;
val sh_val[32] <= shrl(X[rs1]{32}, count);
X[rd] <= sext(sh_val);
}
}
SRAW {
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}";
if(rd != 0){
val mask[32] <= 0x1f;
val count[32] <= X[rs2]{32} & mask;
val sh_val[32] <= shra(X[rs1]{32}, count);
X[rd] <= sext(sh_val);
}
}
}
}

View File

@ -1,210 +0,0 @@
import "RISCVBase.core_desc"
InsructionSet RV32A extends RISCVBase{
instructions{
LR.W {
encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}";
if(rd!=0){
val offs[XLEN] <= X[rs1];
X[rd]<= sext(MEM[offs]{32}, XLEN);
RES[offs]{32}<=sext(-1, 32);
}
}
SC.W {
encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)}";
val offs[XLEN] <= X[rs1];
val res1[32] <= RES[offs]{32};
if(res1!=0)
MEM[offs]{32} <= X[rs2];
if(rd!=0) X[rd]<= choose(res1!=zext(0, 32), 0, 1);
}
AMOSWAP.W{
encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
if(rd!=0) X[rd]<=sext(MEM[offs]{32});
MEM[offs]{32}<=X[rs2];
}
AMOADD.W{
encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 + X[rs2];
MEM[offs]{32}<=res2;
}
AMOXOR.W{
encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 ^ X[rs2];
MEM[offs]{32}<=res2;
}
AMOAND.W{
encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN] <=res1 & X[rs2];
MEM[offs]{32}<=res2;
}
AMOOR.W {
encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 | X[rs2];
MEM[offs]{32}<=res2;
}
AMOMIN.W{
encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd] <= res1;
val res2[XLEN] <= choose(res1's > X[rs2]s, X[rs2], res1);
MEM[offs]{32} <= res2;
}
AMOMAX.W{
encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMINU.W{
encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMAXU.W{
encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd] <= res1;
val res2[XLEN] <= choose(res1 < X[rs2], X[rs2], res1);
MEM[offs]{32} <= res2;
}
}
}
InsructionSet RV64A extends RV32A {
instructions{
LR.D {
encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}";
if(rd!=0){
val offs[XLEN] <= X[rs1];
X[rd]<= sext(MEM[offs]{64}, XLEN);
RES[offs]{64}<=sext(-1, 64);
}
}
SC.D {
encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)}";
val offs[XLEN] <= X[rs1];
val res[64] <= RES[offs];
if(res!=0){
MEM[offs]{64} <= X[rs2];
if(rd!=0) X[rd]<=0;
} else{
if(rd!=0) X[rd]<= 1;
}
}
AMOSWAP.D{
encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
if(rd!=0) X[rd] <= sext(MEM[offs]{64});
MEM[offs]{64} <= X[rs2];
}
AMOADD.D{
encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd]<=res;
val res2[XLEN] <= res + X[rs2];
MEM[offs]{64}<=res2;
}
AMOXOR.D{
encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res;
val res2[XLEN] <= res ^ X[rs2];
MEM[offs]{64} <= res2;
}
AMOAND.D{
encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res;
val res2[XLEN] <= res & X[rs2];
MEM[offs]{64} <= res2;
}
AMOOR.D {
encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res;
val res2[XLEN] <= res | X[rs2];
MEM[offs]{64} <= res2;
}
AMOMIN.D{
encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res1[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res1;
val res2[XLEN] <= choose(res1's > X[rs2]s, X[rs2], res1);
MEM[offs]{64} <= res2;
}
AMOMAX.D{
encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res;
val res2[XLEN] <= choose(res s < X[rs2]s, X[rs2], res);
MEM[offs]{64} <= res2;
}
AMOMINU.D{
encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res;
val res2[XLEN] <= choose(res > X[rs2], X[rs2], res);
MEM[offs]{64} <= res2;
}
AMOMAXU.D{
encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111;
args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})";
val offs[XLEN] <= X[rs1];
val res1[XLEN] <= sext(MEM[offs]{64});
if(rd!=0) X[rd] <= res1;
val res2[XLEN] <= choose(res1 < X[rs2], X[rs2], res1);
MEM[offs]{64} <= res2;
}
}
}

View File

@ -1,373 +0,0 @@
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(no_cont) { // Defined Illegal Instruction
encoding:b000 | b0 | b00000 | b00000 | b00;
raise(0, 2);
}
}
}
InsructionSet RV32FC extends RISCVBase{
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 RISCVBase{
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.SRLI64 {//(RV64)
encoding:b1000 | b00 | rs1[2:0] | 00000 | 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;
}
}
}

View File

@ -1,360 +0,0 @@
import "RISCVBase.core_desc"
InsructionSet RV32D extends RISCVBase{
constants {
FLEN, FFLAG_MASK := 0x1f
}
registers {
[31:0] F[FLEN], FCSR[32]
}
instructions{
FLD {
encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111;
args_disass:"f{rd}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSD {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111;
args_disass:"f{rs2}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
MEM[offs]{64}<=F[rs2]{64};
}
FMADD.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMSUB.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMADD.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMSUB.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FADD.D {
encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f + F[rs2]f;
val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSUB.D {
encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f - F[rs2]f;
val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMUL.D {
encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f * F[rs2]f;
val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FDIV.D {
encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f / F[rs2]f;
val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSQRT.D {
encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
//F[rd]f<=sqrt(F[rs1]f);
val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSGNJ.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
val ONE[64] <= 1;
val MSK1[64] <= ONE<<63;
val MSK2[64] <= MSK1-1;
val res[64] <= (F[rs1]{64} & MSK2) | (F[rs2]{64} & MSK1);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSGNJN.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
val ONE[64] <= 1;
val MSK1[64] <= ONE<<63;
val MSK2[64] <= MSK1-1;
val res[64] <= (F[rs1]{64} & MSK2) | (~F[rs2]{64} & MSK1);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSGNJX.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
val ONE[64] <= 1;
val MSK1[64] <= ONE<<63;
val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & MSK1);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FMIN.D {
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMAX.D {
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.S.D {
encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}";
val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8});
// NaN boxing
val upper[FLEN] <= -1;
F[rd] <= upper<<32 | zext(res, FLEN);
}
FCVT.D.S {
encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}";
val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8});
if(FLEN==64){
F[rd] <= res;
} else {
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FEQ.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
X[rd]<=zext(fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLT.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
X[rd]<=zext(fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32)));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLE.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
X[rd]<=zext(fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCLASS.D {
encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<=fdispatch_fclass_d(F[rs1]{64});
}
FCVT.W.D {
encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<= sext(fdispatch_fcvt_64_32(F[rs1]{64}, zext(0, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.WU.D {
encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
//FIXME: should be zext accodring to spec but needs to be sext according to tests
X[rd]<= sext(fdispatch_fcvt_64_32(F[rs1]{64}, zext(1, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.D.W {
encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
val res[64] <= fdispatch_fcvt_32_64(sext(X[rs1]{32},64), zext(2, 32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FCVT.D.WU {
encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
val res[64] <=fdispatch_fcvt_32_64(zext(X[rs1]{32},64), zext(3,32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
}
}
InsructionSet RV64D extends RV32D{
instructions{
FCVT.L.D {
encoding: b1100001 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.LU.D {
encoding: b1100001 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.D.L {
encoding: b1101001 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FCVT.D.LU {
encoding: b1101001 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FMV.X.D {
encoding: b1110001 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<=sext(F[rs1]);
}
FMV.D.X {
encoding: b1111001 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
F[rd] <= zext(X[rs1]);
}
}
}

View File

@ -1,400 +0,0 @@
import "RV32I.core_desc"
InsructionSet RV32F extends RV32I{
constants {
FLEN, FFLAG_MASK := 0x1f
}
registers {
[31:0] F[FLEN], FCSR[32]
}
instructions{
FLW {
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111;
args_disass:"f{rd}, {imm}({name(rs1)})";
val offs[XLEN] <= X[rs1]'s + imm;
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);
}
}
FSW {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111;
args_disass:"f{rs2}, {imm}({name(rs1)])";
val offs[XLEN] <= X[rs1]'s + imm;
MEM[offs]{32}<=F[rs2]{32};
}
FMADD.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
if(FLEN==32)
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMSUB.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
if(FLEN==32)
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMADD.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
args_disass:"name(rd), f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
if(FLEN==32)
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMSUB.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}";
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
if(FLEN==32)
F[rd] <= fdispatch_fmadd_s(F[rs1], F[rs2], F[rs3], zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val frs3[32] <= fdispatch_unbox_s(F[rs3]);
val res[32] <= fdispatch_fmadd_s(frs1, frs2, frs3, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FADD.S {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f + F[rs2]f;
if(FLEN==32)
F[rd] <= fdispatch_fadd_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= fdispatch_fadd_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSUB.S {
encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f - F[rs2]f;
if(FLEN==32)
F[rd] <= fdispatch_fsub_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= fdispatch_fsub_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMUL.S {
encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f * F[rs2]f;
if(FLEN==32)
F[rd] <= fdispatch_fmul_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= fdispatch_fmul_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FDIV.S {
encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
// F[rd]f <= F[rs1]f / F[rs2]f;
if(FLEN==32)
F[rd] <= fdispatch_fdiv_s(F[rs1], F[rs2], choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= fdispatch_fdiv_s(frs1, frs2, choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSQRT.S {
encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}";
//F[rd]f<=sqrt(F[rs1]f);
if(FLEN==32)
F[rd] <= fdispatch_fsqrt_s(F[rs1], choose(rm<7, rm{8}, FCSR{8}));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val res[32] <= fdispatch_fsqrt_s(frs1, choose(rm<7, rm{8}, FCSR{8}));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSGNJ.S {
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
if(FLEN==32)
F[rd] <= (F[rs1] & 0x7fffffff) | (F[rs2] & 0x80000000);
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= (frs1 & 0x7fffffff) | (frs2 & 0x80000000);
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FSGNJN.S {
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
if(FLEN==32)
F[rd] <= (F[rs1] & 0x7fffffff) | (~F[rs2] & 0x80000000);
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= (frs1 & 0x7fffffff) | (~frs2 & 0x80000000);
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FSGNJX.S {
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
if(FLEN==32)
F[rd] <= F[rs1] ^ (F[rs2] & 0x80000000);
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= frs1 ^ (frs2 & 0x80000000);
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FMIN.S {
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
if(FLEN==32)
F[rd] <= fdispatch_fsel_s(F[rs1], F[rs2], zext(0, 32));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= fdispatch_fsel_s(frs1, frs2, zext(0, 32));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMAX.S {
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f{rd}, f{rs1}, f{rs2}";
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
if(FLEN==32)
F[rd] <= fdispatch_fsel_s(F[rs1], F[rs2], zext(1, 32));
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
val res[32] <= fdispatch_fsel_s(frs1, frs2, zext(1, 32));
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.W.S {
encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
if(FLEN==32)
X[rd] <= sext(fdispatch_fcvt_s(F[rs1], zext(0, 32), rm{8}), XLEN);
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
X[rd]<= sext(fdispatch_fcvt_s(frs1, zext(0, 32), rm{8}), XLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.WU.S {
encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
//FIXME: according to the spec it should be zero-extended not sign extended
if(FLEN==32)
X[rd]<= sext(fdispatch_fcvt_s(F[rs1], zext(1, 32), rm{8}), XLEN);
else { // NaN boxing
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
X[rd]<= sext(fdispatch_fcvt_s(frs1, zext(1, 32), rm{8}), XLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FEQ.S {
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
if(FLEN==32)
X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(0, 32)));
else {
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(0, 32)));
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLT.S {
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
if(FLEN==32)
X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(2, 32)));
else {
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(2, 32)));
}
X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLE.S {
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}, f{rs2}";
if(FLEN==32)
X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(1, 32)));
else {
val frs1[32] <= fdispatch_unbox_s(F[rs1]);
val frs2[32] <= fdispatch_unbox_s(F[rs2]);
X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(1, 32)));
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCLASS.S {
encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<=fdispatch_fclass_s(fdispatch_unbox_s(F[rs1]));
}
FCVT.S.W {
encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
if(FLEN==32)
F[rd] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8});
else { // NaN boxing
val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8});
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FCVT.S.WU {
encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
if(FLEN==32)
F[rd] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8});
else { // NaN boxing
val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8});
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FMV.X.W {
encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
X[rd]<=sext(F[rs1]{32});
}
FMV.W.X {
encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
if(FLEN==32)
F[rd] <= X[rs1]{32};
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(X[rs1]{32}, FLEN);
}
}
}
}
InsructionSet RV64F extends RV32F{
instructions{
FCVT.L.S { // fp to 64bit signed integer
encoding: b1100000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
val res[64] <= fdispatch_fcvt_32_64(fdispatch_unbox_s(F[rs1]), zext(0, 32), rm{8});
X[rd]<= sext(res);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.LU.S { // fp to 64bit unsigned integer
encoding: b1100000 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"{name(rd)}, f{rs1}";
val res[64] <= fdispatch_fcvt_32_64(fdispatch_unbox_s(F[rs1]), zext(1, 32), rm{8});
X[rd]<= zext(res);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.S.L { // 64bit signed int to to fp
encoding: b1101000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
val res[32] <= fdispatch_fcvt_64_32(X[rs1], zext(2, 32), rm{8});
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FCVT.S.LU { // 64bit unsigned int to to fp
encoding: b1101000 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f{rd}, {name(rs1)}";
val res[32] <=fdispatch_fcvt_64_32(X[rs1], zext(3,32), rm{8});
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
}
}

View File

@ -1,160 +0,0 @@
import "RISCVBase.core_desc"
InsructionSet RV32M extends RISCVBase {
constants {
MUL_LEN
}
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[MUL_LEN] <= zext(X[rs1], MUL_LEN) * zext(X[rs2], MUL_LEN);
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[MUL_LEN] <= sext(X[rs1], MUL_LEN) * sext(X[rs2], MUL_LEN);
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[MUL_LEN] <= sext(X[rs1], MUL_LEN) * zext(X[rs2], MUL_LEN);
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[MUL_LEN] <= zext(X[rs1], MUL_LEN) * zext(X[rs2], MUL_LEN);
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});
}
}
}
}