Refactored core descriptions
This commit is contained in:
parent
f69b529cab
commit
3e8583977a
50
riscv/gen_input/RISCVBase.core_desc
Normal file
50
riscv/gen_input/RISCVBase.core_desc
Normal file
@ -0,0 +1,50 @@
|
||||
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]
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
import "RV32IBase.core_desc"
|
||||
|
||||
InsructionSet RV32A extends RV32IBase{
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,52 +1,6 @@
|
||||
InsructionSet RV32IBase {
|
||||
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]
|
||||
}
|
||||
import "RISCVBase.core_desc"
|
||||
|
||||
InsructionSet RV32I extends RISCVBase{
|
||||
|
||||
instructions {
|
||||
LUI{
|
@ -1,6 +1,6 @@
|
||||
import "RV32IBase.core_desc"
|
||||
import "RV32I.core_desc"
|
||||
|
||||
InsructionSet RV64IBase extends RV32IBase {
|
||||
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;
|
@ -1,65 +0,0 @@
|
||||
import "RV64IBase.core_desc"
|
||||
|
||||
InsructionSet RV64M extends RV64IBase {
|
||||
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});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,109 @@
|
||||
import "RV64IBase.core_desc"
|
||||
import "RISCVBase.core_desc"
|
||||
|
||||
InsructionSet RV64A extends RV64IBase {
|
||||
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 {
|
||||
@ -104,4 +207,4 @@ InsructionSet RV64A extends RV64IBase {
|
||||
MEM[offs]{64} <= res2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,16 +1,7 @@
|
||||
import "RV32IBase.core_desc"
|
||||
import "RISCVBase.core_desc"
|
||||
|
||||
InsructionSet RV32IC extends RISCVBase{
|
||||
|
||||
InsructionSet RV32IC {
|
||||
constants {
|
||||
XLEN
|
||||
}
|
||||
address_spaces {
|
||||
MEM[8]
|
||||
}
|
||||
registers {
|
||||
[31:0] X[XLEN],
|
||||
PC[XLEN](is_pc)
|
||||
}
|
||||
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;
|
||||
@ -182,13 +173,9 @@ InsructionSet RV32IC {
|
||||
|
||||
InsructionSet RV32FC extends RV32IC{
|
||||
constants {
|
||||
XLEN, FLEN
|
||||
}
|
||||
address_spaces {
|
||||
MEM[8]
|
||||
FLEN
|
||||
}
|
||||
registers {
|
||||
[31:0] X[XLEN],
|
||||
[31:0] F[FLEN]
|
||||
}
|
||||
instructions{
|
||||
@ -233,13 +220,9 @@ InsructionSet RV32FC extends RV32IC{
|
||||
|
||||
InsructionSet RV32DC extends RV32IC{
|
||||
constants {
|
||||
XLEN, FLEN
|
||||
}
|
||||
address_spaces {
|
||||
MEM[8]
|
||||
FLEN
|
||||
}
|
||||
registers {
|
||||
[31:0] X[XLEN],
|
||||
[31:0] F[FLEN]
|
||||
}
|
||||
instructions{
|
||||
@ -283,16 +266,7 @@ InsructionSet RV32DC extends RV32IC{
|
||||
}
|
||||
|
||||
InsructionSet RV64IC extends RV32IC {
|
||||
constants {
|
||||
XLEN
|
||||
}
|
||||
address_spaces {
|
||||
MEM[8]
|
||||
}
|
||||
registers {
|
||||
[31:0] X[XLEN],
|
||||
PC[XLEN](is_pc)
|
||||
}
|
||||
|
||||
instructions{
|
||||
C.LD {//(RV64/128)
|
||||
encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
|
||||
@ -360,16 +334,7 @@ InsructionSet RV64IC extends RV32IC {
|
||||
}
|
||||
|
||||
InsructionSet RV128IC extends RV64IC {
|
||||
constants {
|
||||
XLEN
|
||||
}
|
||||
address_spaces {
|
||||
MEM[8]
|
||||
}
|
||||
registers {
|
||||
[31:0] X[XLEN],
|
||||
PC[XLEN](is_pc)
|
||||
}
|
||||
|
||||
instructions{
|
||||
C.SRLI {//(RV128)
|
||||
encoding:b100 | shamt[5:5] | b00 | rs1[2:0] | shamt[4:0] | b01;
|
@ -1,6 +1,6 @@
|
||||
import "RV32IBase.core_desc"
|
||||
import "RISCVBase.core_desc"
|
||||
|
||||
InsructionSet RV32D extends RV32IBase{
|
||||
InsructionSet RV32D extends RISCVBase{
|
||||
constants {
|
||||
FLEN, FFLAG_MASK := 0x1f
|
||||
}
|
||||
@ -306,12 +306,7 @@ InsructionSet RV32D extends RV32IBase{
|
||||
}
|
||||
}
|
||||
InsructionSet RV64D extends RV32D{
|
||||
constants {
|
||||
FLEN, FFLAG_MASK := 0x1f
|
||||
}
|
||||
registers {
|
||||
[31:0] F[FLEN], FCSR[32]
|
||||
}
|
||||
|
||||
instructions{
|
||||
FCVT.L.D {
|
||||
encoding: b1100001 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||
@ -359,7 +354,6 @@ InsructionSet RV64D extends RV32D{
|
||||
args_disass:"f{rd}, {name(rs1)}";
|
||||
F[rd] <= zext(X[rs1]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import "RV32IBase.core_desc"
|
||||
import "RV32I.core_desc"
|
||||
|
||||
InsructionSet RV32F extends RV32IBase{
|
||||
InsructionSet RV32F extends RV32I{
|
||||
constants {
|
||||
FLEN, FFLAG_MASK := 0x1f
|
||||
}
|
||||
@ -355,12 +355,7 @@ InsructionSet RV32F extends RV32IBase{
|
||||
}
|
||||
|
||||
InsructionSet RV64F extends RV32F{
|
||||
constants {
|
||||
FLEN, FFLAG_MASK := 0x1f
|
||||
}
|
||||
registers {
|
||||
[31:0] F[FLEN], FCSR[32]
|
||||
}
|
||||
|
||||
instructions{
|
||||
FCVT.L.S { // fp to 64bit signed integer
|
||||
encoding: b1100000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
@ -1,6 +1,6 @@
|
||||
import "RV32IBase.core_desc"
|
||||
import "RISCVBase.core_desc"
|
||||
|
||||
InsructionSet RV32M extends RV32IBase {
|
||||
InsructionSet RV32M extends RISCVBase {
|
||||
constants {
|
||||
MAXLEN:=128
|
||||
}
|
||||
@ -92,4 +92,69 @@ InsructionSet RV32M extends RV32IBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,12 @@
|
||||
import "RV32IBase.core_desc"
|
||||
import "RV32M.core_desc"
|
||||
import "RV32A.core_desc"
|
||||
import "RV32C.core_desc"
|
||||
import "RV32F.core_desc"
|
||||
import "RV32D.core_desc"
|
||||
import "RV64IBase.core_desc"
|
||||
import "RV64M.core_desc"
|
||||
import "RV64A.core_desc"
|
||||
import "RV32I.core_desc"
|
||||
import "RV64I.core_desc"
|
||||
import "RVM.core_desc"
|
||||
import "RVA.core_desc"
|
||||
import "RVC.core_desc"
|
||||
import "RVF.core_desc"
|
||||
import "RVD.core_desc"
|
||||
|
||||
Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC {
|
||||
Core RV32IMAC provides RV32I, RV32M, RV32A, RV32IC {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
PCLEN:=32;
|
||||
@ -20,7 +18,7 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC {
|
||||
}
|
||||
}
|
||||
|
||||
Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32DC {
|
||||
Core RV32GC provides RV32I, RV32M, RV32A, RV32F, RV32D, RV32IC, RV32FC, RV32DC {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
FLEN:=64;
|
||||
@ -33,7 +31,7 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32
|
||||
}
|
||||
}
|
||||
|
||||
Core RV64I provides RV64IBase {
|
||||
Core RV64I provides RV64I {
|
||||
constants {
|
||||
XLEN:=64;
|
||||
PCLEN:=64;
|
||||
@ -45,7 +43,7 @@ Core RV64I provides RV64IBase {
|
||||
}
|
||||
}
|
||||
|
||||
Core RV64GC provides RV64IC, RV64A, RV64M, RV32A, RV32M, RV64F, RV64D, RV32FC, RV32DC {
|
||||
Core RV64GC provides RV64I, RV64M, RV64A, RV64F, RV64D, RV64IC, RV32FC, RV32DC {
|
||||
constants {
|
||||
XLEN:=64;
|
||||
FLEN:=64;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user