Skip to content

Commit

Permalink
RV32M and RV64M support
Browse files Browse the repository at this point in the history
  • Loading branch information
Geetis committed Mar 28, 2024
1 parent c0fa1ed commit 4e993b8
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 9 deletions.
10 changes: 10 additions & 0 deletions src/emulation_core/riscv/control_signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ pub enum AluOp {

/// `_1110` (14) - Perform unsigned integer division. (Returns the integer quotient.)
DivisionUnsigned,

MultiplicationSignedUpper,

MultiplicationSignedUnsignedUpper,

MultiplicationUnsignedSignedUpper,

RemainderSigned,

RemainderUnsigned,
}

#[derive(Clone, Default, PartialEq)]
Expand Down
63 changes: 57 additions & 6 deletions src/emulation_core/riscv/datapath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,19 +636,45 @@ impl RiscDatapath {
0 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::Addition,
0b0100000 => self.signals.alu_op = AluOp::Subtraction,
0b0000001 => self.signals.alu_op = AluOp::MultiplicationSigned,
_ => (),
},
1 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::ShiftLeftLogical(self.state.rs2),
0b0000001 => self.signals.alu_op = AluOp::MultiplicationSignedUpper,
_ => (),
},
2 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::SetOnLessThanSigned,
0b0000001 => self.signals.alu_op = AluOp::MultiplicationSignedUnsignedUpper,
_ => (),
},
3 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::SetOnLessThanUnsigned,
0b0000001 => self.signals.alu_op = AluOp::MultiplicationUnsignedSignedUpper,
_ => (),
},
4 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::Xor,
0b0000001 => self.signals.alu_op = AluOp::DivisionSigned,
_ => (),
},
1 => self.signals.alu_op = AluOp::ShiftLeftLogical(self.state.rs2),
2 => self.signals.alu_op = AluOp::SetOnLessThanSigned,
3 => self.signals.alu_op = AluOp::SetOnLessThanUnsigned,
4 => self.signals.alu_op = AluOp::Xor,
5 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::ShiftRightLogical(self.state.rs2),
0b0100000 => self.signals.alu_op = AluOp::ShiftRightArithmetic(self.state.rs2),
0b0000001 => self.signals.alu_op = AluOp::DivisionUnsigned,
_ => (),
},
6 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::Or,
0b0000001 => self.signals.alu_op = AluOp::RemainderSigned,
_ => (),
},
7 => match r.funct7 {
0b0000000 => self.signals.alu_op = AluOp::And,
0b0000001 => self.signals.alu_op = AluOp::RemainderUnsigned,
_ => (),
},
6 => self.signals.alu_op = AluOp::Or,
7 => self.signals.alu_op = AluOp::And,
_ => (),
}
}
Expand Down Expand Up @@ -875,6 +901,17 @@ impl RiscDatapath {
AluOp::MultiplicationUnsigned => {
((self.state.alu_input1 as u128) * (self.state.alu_input2 as u128)) as u64
}
AluOp::MultiplicationSignedUpper => {
(((self.state.alu_input1 as i128) * (self.state.alu_input2 as i128)) >> 64) as u64
}
AluOp::MultiplicationSignedUnsignedUpper => {
(((self.state.alu_input1 as i128) * (self.state.alu_input2 as u128 as i128)) >> 64)
as u64
}
AluOp::MultiplicationUnsignedSignedUpper => {
(((self.state.alu_input1 as u128 as i128) * (self.state.alu_input2 as i128)) >> 64)
as u64
}
AluOp::DivisionSigned => {
if self.state.alu_input2 == 0 {
0
Expand All @@ -889,6 +926,20 @@ impl RiscDatapath {
self.state.alu_input1 / self.state.alu_input2
}
}
AluOp::RemainderSigned => {
if self.state.alu_input2 == 0 {
0
} else {
((self.state.alu_input1 as i64) % (self.state.alu_input2 as i64)) as u64
}
}
AluOp::RemainderUnsigned => {
if self.state.alu_input2 == 0 {
0
} else {
self.state.alu_input1 % self.state.alu_input2
}
}
_ => 0,
};

Expand Down
6 changes: 3 additions & 3 deletions static/assembly_examples/riscv_test.asm
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
main:
jal x1, 2044
fmv.s f1, f2
ret
addi x1, x0, 50
addi x2, x0, 2
mul x3, x1, x2

0 comments on commit 4e993b8

Please sign in to comment.