riscii

An emulator for the RISC II
Log | Files | Refs | LICENSE

commit d5803d8d078c79dd1c73ab31c56a1384124eba5e
parent fc978975c6fb9a3fddd5dbb64cfdfd0bcc3ee9ee
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date:   Sat, 15 Oct 2022 14:06:06 -0700

ALU

Diffstat:
Asrc/alu.rs | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/data_path.rs | 15+++++++--------
Msrc/main.rs | 1+
3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/src/alu.rs b/src/alu.rs @@ -0,0 +1,102 @@ +// RISCII ALU emulator. +// (C) Ryan Jeffrey <ryan@ryanmj.xyz>, 2022 +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. + +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +// Public structs. + +use std::fmt; + +/// Representation of the Arithmetic Logic Unit of the RISCII. +/// Implements bitwise and arithmetic operations, except for shifts. +#[derive(Clone, Copy)] +pub struct ALU { + /// Input latch 1 for the ALU (fed by src1 or dest). + pub ai: u32, + /// Input latch 2 for the ALU (fed by src2 or dest). + pub bi: u32, +} + +// Impls. + +impl ALU { + /// Create a 0'd out ALU. + pub fn new() -> Self { + Self { ai: 0, bi: 0 } + } + + // Bitwise. + + /// Bitwise AND the values in the input latches. + pub fn and(&self) -> u32 { + self.ai & self.bi + } + + /// Bitwise OR the values in the input latches. + pub fn or(&self) -> u32 { + self.ai | self.bi + } + + /// Bitwise XOR the values in the input latches. + pub fn xor(&self) -> u32 { + self.ai ^ self.bi + } + + // Arithmetics. + + /// Add the values in the input latches. + pub fn add(&self) -> u32 { + self.ai + self.bi + } + + /// Add the values in the input latches with the carry bit. + pub fn addc(&self, carry: bool) -> u32 { + self.ai + self.bi + (carry as u32) + } + + /// Subtract the values in the input latches. + pub fn sub(&self) -> u32 { + self.ai - self.bi + } + + /// Subtract the values in the input latches with the carry bit. + pub fn subc(&self, carry: bool) -> u32 { + self.ai - self.bi - (!carry as u32) + } + + /// Subtract (inverse) the values in the input latches. + pub fn subi(&self) -> u32 { + self.bi - self.ai + } + + /// Subtract (inverse) the values in the input latches with the carry bit. + pub fn subci(&self, carry: bool) -> u32 { + self.bi - self.ai - (!carry as u32) + } +} + +impl fmt::Display for ALU { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}, {}", self.ai, self.bi,) + } +} + +impl fmt::Debug for ALU { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Input register: {}, Output register: {}", + self.ai, self.bi, + ) + } +} diff --git a/src/data_path.rs b/src/data_path.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. +use alu::ALU; use config::Config; use cpu::{OutputPins, ProcessorStatusWord, RegisterFile, SIZEOF_INSTRUCTION}; use instruction::*; @@ -54,10 +55,9 @@ pub struct DataPath { pins_in: u32, /// Pins for communicating with the outside world (memory). output_pins: OutputPins, - /// Input latch 1 for the ALU (fed by src1). - ai: u32, - /// Input latch 2 for the ALU (fed by src2). - bi: u32, + /// Arithmetic logic unit. + alu: ALU, + // Control unit latches and registers. /// Data from memory. dimm: u32, @@ -110,8 +110,7 @@ impl DataPath { psw: ProcessorStatusWord::new(), src_latch: 0, dst_latch: 0, - ai: 0, - bi: 0, + alu: ALU::new(), bar: 0, rd1: 0, rd2: 0, @@ -151,8 +150,8 @@ impl DataPath { let cwp = self.psw.get_cwp(); let read1 = self.regs.read(src1, cwp); let read2 = self.regs.read(src2, cwp); - self.ai = read1; - self.bi = read2; + self.alu.ai = read1; + self.alu.bi = read2; } /// Decode the next instruction's (in `self.pins_in`) source registers. diff --git a/src/main.rs b/src/main.rs @@ -25,6 +25,7 @@ mod encode_test; mod main_test; // Modules declared as pub to shut up rust-analyzer about dead code. +pub mod alu; pub mod clock; pub mod config; pub mod cpu;