Skip to content

Commit

Permalink
Fixed sign extension
Browse files Browse the repository at this point in the history
  • Loading branch information
Geetis committed Mar 29, 2024
1 parent dc7adcf commit 7428f07
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 17 deletions.
58 changes: 45 additions & 13 deletions src/emulation_core/riscv/datapath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ use crate::emulation_core::stack::Stack;
use crate::emulation_core::stack::StackFrame;
use serde::{Deserialize, Serialize};

use gloo_console::log;

/// An implementation of a datapath for the MIPS64 ISA.
#[derive(Clone, PartialEq)]
pub struct RiscDatapath {
Expand Down Expand Up @@ -95,9 +97,9 @@ pub struct RiscDatapathState {
pub shamt: u32,
pub funct3: u32,
pub funct7: u32,
pub imm: u32,
pub imm1: u32,
pub imm2: u32,
pub imm: i32,
pub imm1: i32,
pub imm2: i32,

/// *Data line.* The first input of the ALU.
pub alu_input1: u64,
Expand Down Expand Up @@ -212,7 +214,7 @@ impl Default for RiscDatapath {

// Set the stack pointer ($sp) to initially start at the end
// of memory.
datapath.registers.gpr[29] = super::super::mips::memory::CAPACITY_BYTES as u64;
datapath.registers.gpr[2] = super::super::mips::memory::CAPACITY_BYTES as u64;

datapath
}
Expand Down Expand Up @@ -530,21 +532,21 @@ impl RiscDatapath {
self.state.rs1 = i.rs1 as u32;
self.state.funct3 = i.funct3 as u32;
self.state.rd = i.rd as u32;
self.state.imm = i.imm as u32;
self.state.imm = i.imm as i32;
self.state.shamt = (i.imm & 0x003f) as u32;
}
Instruction::SType(s) => {
self.state.rs2 = s.rs2 as u32;
self.state.rs1 = s.rs1 as u32;
self.state.funct3 = s.funct3 as u32;
self.state.imm1 = s.imm1 as u32;
self.state.imm2 = s.imm2 as u32;
self.state.imm1 = s.imm1 as i32;
self.state.imm2 = s.imm2 as i32;
}
Instruction::BType(b) => {
self.state.rs1 = b.rs1 as u32;
self.state.rs2 = b.rs2 as u32;
self.state.funct3 = b.funct3 as u32;
self.state.imm = b.imm as u32;
self.state.imm = b.imm as i32;
}
Instruction::UType(u) => {
self.state.imm = u.imm;
Expand All @@ -562,12 +564,21 @@ impl RiscDatapath {

fn set_immediate(&mut self) {
let mut signed_imm = 0x0000;
if self.state.instruction >> 31 == 1 {
signed_imm = 0xffffffff;
}
// if self.state.instruction >> 31 == 1 {
// signed_imm = 0xffffffff;
// }

log!("self.state.imm: ", format!("{:012b}", self.state.imm));

signed_imm = match self.signals.imm_select {
ImmSelect::ISigned => (signed_imm << 12) | self.state.imm,
ImmSelect::ISigned => {
let mask = 0b100000000000;
if self.state.imm & mask != 0 {
!(!self.state.imm & 0xFFF)
} else {
self.state.imm
}
}
ImmSelect::IShamt => (signed_imm << 12) | self.state.imm,
ImmSelect::IUnsigned => self.state.imm,
ImmSelect::SType => ((signed_imm << 7) | self.state.imm1) << 5 | self.state.imm2,
Expand All @@ -576,6 +587,9 @@ impl RiscDatapath {
ImmSelect::JType => self.state.imm,
};

log!("signed_imm: ", format!("{:?}", signed_imm));
log!("self.state.imm: ", format!("{:?}", self.state.imm));

self.state.imm = signed_imm;
}

Expand Down Expand Up @@ -854,6 +868,8 @@ impl RiscDatapath {
OP1Select::IMM => self.state.rs1 as u64,
};

log!("self.state.imm (alu): ", format!("{:?}", self.state.imm));

self.state.alu_input2 = match self.signals.op2_select {
OP2Select::DATA2 => self.state.read_data_2,
OP2Select::IMM => self.state.imm as i64 as u64,
Expand All @@ -869,6 +885,15 @@ impl RiscDatapath {
self.state.alu_input2 = self.state.alu_input2 as u32 as i64 as u64;
}

log!(
"self.state.alu_input1: ",
format!("{:?}", self.state.alu_input1)
);
log!(
"self.state.alu_input2: ",
format!("{:?}", self.state.alu_input2)
);

// Set the result.
self.state.alu_result = match self.signals.alu_op {
AluOp::Addition => self.state.alu_input1.wrapping_add(self.state.alu_input2),
Expand Down Expand Up @@ -984,7 +1009,14 @@ impl RiscDatapath {
}

fn calc_relative_pc_branch(&mut self) {
self.state.relative_pc_branch = self.state.imm as u64 * 4;
log!("calc_relative_pc_branch");
log!(
"self.state.imm as u64",
format!("{:?}", self.state.imm as u64)
);
if self.state.imm > 0 {
self.state.relative_pc_branch = self.state.imm as u64 * 4;
}
}

/// Determine the value of the [`CpuBranch`] signal.
Expand Down
8 changes: 4 additions & 4 deletions src/emulation_core/riscv/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ pub struct BType {

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct UType {
pub imm: u32,
pub imm: i32,
pub rd: u8,
pub op: u8,
}

#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct JType {
pub imm: u32,
pub imm: i32,
pub rd: u8,
pub op: u8,
}
Expand Down Expand Up @@ -149,14 +149,14 @@ impl TryFrom<u32> for Instruction {

// U-type instruction:
OPCODE_LUI | OPCODE_AUIPC => Ok(Instruction::UType(UType {
imm: value >> 12,
imm: (value >> 12) as i32,
rd: ((value >> 7) & 0x1f) as u8,
op: (value & 0x7f) as u8,
})),

// J-type instruction:
OPCODE_JAL => Ok(Instruction::JType(JType {
imm: value >> 12,
imm: (value >> 12) as i32,
rd: ((value >> 7) & 0x1f) as u8,
op: (value & 0x7f) as u8,
})),
Expand Down

0 comments on commit 7428f07

Please sign in to comment.