riscii

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

commit 36d910f5b7e3ad8280fae94d5513244225595789
parent 70bd0819463984cfaacab1087f70f491907611f1
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date:   Wed,  9 Nov 2022 22:21:50 -0800

Complete data path

Diffstat:
Msrc/cpu.rs | 2+-
Msrc/data_path.rs | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/debug_window.rs | 126++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/instruction.rs | 6+++---
Msrc/shifter.rs | 14++++++++++----
Msrc/system.rs | 12++++++++++++
6 files changed, 239 insertions(+), 26 deletions(-)

diff --git a/src/cpu.rs b/src/cpu.rs @@ -403,7 +403,7 @@ impl ProcessorStatusWord { impl fmt::Display for ProcessorStatusWord { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "0x{:x}", self.0) + write!(f, "{:03x}", self.0) } } diff --git a/src/data_path.rs b/src/data_path.rs @@ -18,14 +18,10 @@ use config::Config; use cpu::{OutputPins, ProcessorStatusWord, RegisterFile, SIZEOF_INSTRUCTION}; use instruction::*; use memory::Memory; -use shifter; +use shifter::Shifter; use std::fmt; use util::Result; -use crate::shifter::Shifter; - -pub type MicroOp = fn(dp: &mut DataPath); - pub struct SCCBits { pub z: bool, pub n: bool, @@ -381,9 +377,36 @@ impl DataPath { // Callr long = true; immediate = true; + + result = InstructionCycle { + 0: [ + noop, + noop, + |dp: &mut DataPath| -> () { + dp.callr_step3(); + }, + noop, + |dp: &mut DataPath| -> () { + dp.commit_callr(); + }, + ], + }; } 12 => { // Jmpx + result = InstructionCycle { + 0: [ + noop, + noop, + |dp: &mut DataPath| -> () { + dp.jmpx_step3(); + }, + noop, + |dp: &mut DataPath| -> () { + dp.commit_jmpx(); + }, + ], + }; } 13 => { // Jmpr @@ -421,6 +444,26 @@ impl DataPath { result } + fn callr_step3(&mut self) { + // Calculate value and send it to dest. + let eff_addr = self.alu.add(); + + self.dst_latch = eff_addr; + } + + fn jmpx_step3(&mut self) { + // + } + + fn commit_jmpx(&mut self) { + // + self.nxtpc = self.dst_latch; + } + + fn commit_callr(&mut self) { + // + } + pub fn current_instruction_is_memory(&self) -> bool { self.control2.memory } @@ -437,6 +480,58 @@ impl DataPath { self.psw.set_cc_neg(self.dst_latch & SIGN_BIT_LOC != 0); } } + + pub fn decode_source_registers(&self) -> (u8, u8) { + (self.rs1_1, self.rs2_1) + } + + pub fn execute_source_registers(&self) -> (u8, u8) { + (self.rs1_2, self.rs2_2) + } + + pub fn decode_destination_register(&self) -> u8 { + self.rd1 + } + + pub fn execute_destination_register(&self) -> u8 { + self.rd2 + } + + pub fn commit_destination_register(&self) -> u8 { + self.rd3 + } + + pub fn decode_rd(&self) -> u8 { + self.rd1 + } + + pub fn execute_rd(&self) -> u8 { + self.rd2 + } + + pub fn bar(&self) -> u8 { + self.bar + } + + pub fn imm(&self) -> u32 { + self.imm + } + + pub fn execute_op(&self) -> u8 { + self.op1 + } + + pub fn register_file(&self) -> &RegisterFile { + &self.regs + } + + pub fn psw(&self) -> ProcessorStatusWord { + self.psw.clone() + } + + pub fn shifter(&self) -> Shifter { + self.shifter + } } impl Control { diff --git a/src/debug_window.rs b/src/debug_window.rs @@ -132,7 +132,7 @@ impl<'a> Drawable for DebugWindow<'a> { Phase::Four => "φ₄", Phase::Interrupt => "φᵢ", }, - Rect::new(1400, 0, 50, 50), + Rect::new(1550, 0, 50, 50), OBJ_DEFAULT_COLOR, )?; @@ -186,7 +186,7 @@ impl<'a> Drawable for DebugWindow<'a> { self.draw_lines( &[ (400, 525, 1275, 525), - (815, 525, 815, 425), + (815, 525, 815, 450), (850, 525, 850, 575), (850, 575, 875, 575), ], @@ -198,18 +198,20 @@ impl<'a> Drawable for DebugWindow<'a> { &[ (400, 640, 850, 640), (850, 640, 850, 750), + (805, 640, 805, 450), (850, 750, 875, 750), ], OBJ_DEFAULT_COLOR, )?; - self.draw_static_str("busR", Rect::new(410, 645, 50, 25), OBJ_DEFAULT_COLOR)?; // busL self.draw_lines( &[ (400, 760, 600, 760), - (600, 760, 810, 500), - (810, 500, 810, 425), + (600, 760, 790, 550), + (790, 550, 790, 350), + (790, 350, 825, 350), + (825, 350, 825, 325), ], OBJ_DEFAULT_COLOR, )?; @@ -235,9 +237,22 @@ impl<'a> Drawable for DebugWindow<'a> { self.draw_static_str("RD", Rect::new(125, 125, 50, 50), OBJ_DEFAULT_COLOR)?; // busext to RD self.pane.canvas.line(150, 50, 150, 75, OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("R{:02}", dp.decode_rd()), + Rect::new(125, 75, 50, 50), + OBJ_DEFAULT_COLOR, + )?; + + // Source register latches + let (rs1, rs2) = dp.decode_source_registers(); // RS1 self.draw_rect(Rect::new(50, 200, 100, 50), OBJ_DEFAULT_COLOR)?; self.draw_static_str("RS1", Rect::new(75, 250, 50, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("R{:02}", rs1), + Rect::new(75, 200, 50, 50), + OBJ_DEFAULT_COLOR, + )?; // busext to RS1 self.draw_line((75, 50, 75, 200), OBJ_DEFAULT_COLOR)?; // RD to RS1 @@ -247,6 +262,11 @@ impl<'a> Drawable for DebugWindow<'a> { // RS2 self.draw_rect(Rect::new(175, 200, 100, 50), OBJ_DEFAULT_COLOR)?; self.draw_static_str("RS2", Rect::new(200, 250, 50, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("R{:02}", rs2), + Rect::new(200, 200, 50, 50), + OBJ_DEFAULT_COLOR, + )?; // busext to RS2 self.draw_line((250, 50, 250, 200), OBJ_DEFAULT_COLOR)?; // RD to RS2 @@ -257,8 +277,16 @@ impl<'a> Drawable for DebugWindow<'a> { // PSW register self.draw_rect(Rect::new(300, 200, 125, 75), OBJ_DEFAULT_COLOR)?; self.draw_static_str("PSW", Rect::new(325, 275, 75, 50), OBJ_DEFAULT_COLOR)?; - // busB to PSW - self.draw_line((310, 700, 310, 275), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("{}", dp.psw()), + Rect::new(325, 225, 75, 50), + OBJ_DEFAULT_COLOR, + )?; + // busB to PSW and SHam + self.draw_lines( + &[(310, 700, 310, 275), (310, 325, 500, 325)], + OBJ_DEFAULT_COLOR, + )?; // PSW to register file self.draw_line((300, 250, 290, 250), OBJ_DEFAULT_COLOR)?; self.draw_line((290, 250, 290, 475), OBJ_DEFAULT_COLOR)?; @@ -266,23 +294,46 @@ impl<'a> Drawable for DebugWindow<'a> { // imm self.draw_rect(Rect::new(800, 100, 100, 50), OBJ_DEFAULT_COLOR)?; self.draw_static_str("IMM", Rect::new(910, 100, 75, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("{:05x}", dp.imm()), + Rect::new(810, 100, 75, 50), + OBJ_DEFAULT_COLOR, + )?; // busEXT to imm self.draw_line((825, 50, 825, 100), OBJ_DEFAULT_COLOR)?; // dimm self.draw_rect(Rect::new(800, 250, 250, 75), OBJ_DEFAULT_COLOR)?; self.draw_static_str("DIn/DIMM", Rect::new(900, 325, 150, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("{:08x}", dp.imm()), + Rect::new(800, 255, 250, 50), + OBJ_DEFAULT_COLOR, + )?; // busEXT to dimm self.draw_line((1000, 50, 1000, 250), OBJ_DEFAULT_COLOR)?; - // imm to dimm - self.draw_line((825, 150, 825, 250), OBJ_DEFAULT_COLOR)?; + // imm to dimm and SHAM + self.draw_lines( + &[ + (825, 150, 825, 250), + (825, 175, 475, 175), + (475, 175, 475, 315), + (475, 315, 500, 315), + ], + OBJ_DEFAULT_COLOR, + )?; // op self.draw_rect(Rect::new(1100, 125, 50, 50), OBJ_DEFAULT_COLOR)?; self.draw_static_str("OP", Rect::new(1100, 175, 50, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("{:02x}", dp.execute_op()), + Rect::new(1100, 125, 50, 50), + OBJ_DEFAULT_COLOR, + )?; // busext to op self.draw_line((1125, 50, 1125, 125), OBJ_DEFAULT_COLOR)?; // Shifter self.draw_rect(Rect::new(600, 500, 175, 300), OBJ_DEFAULT_COLOR)?; - self.draw_static_str("Shifter", Rect::new(600, 450, 100, 50), OBJ_DEFAULT_COLOR)?; + self.draw_static_str("Shifter", Rect::new(600, 800, 100, 50), OBJ_DEFAULT_COLOR)?; self.draw_circle((690, 650, 50), OBJ_DEFAULT_COLOR)?; // ALU @@ -294,16 +345,65 @@ impl<'a> Drawable for DebugWindow<'a> { self.draw_static_str("ALU", Rect::new(900, 450, 75, 50), OBJ_DEFAULT_COLOR)?; // AI (ALU input latch) self.draw_rect(Rect::new(875, 500, 25, 120), OBJ_DEFAULT_COLOR)?; - self.draw_static_str("BAR", Rect::new(825, 450, 50, 50), OBJ_DEFAULT_COLOR)?; + self.draw_static_str("AI", Rect::new(825, 450, 50, 50), OBJ_DEFAULT_COLOR)?; // BI (ALU input latch) self.draw_rect(Rect::new(875, 680, 25, 120), OBJ_DEFAULT_COLOR)?; self.draw_static_str("BI", Rect::new(825, 800, 50, 50), OBJ_DEFAULT_COLOR)?; // BAR - self.draw_rect(Rect::new(800, 400, 25, 25), OBJ_DEFAULT_COLOR)?; - self.draw_static_str("BAR", Rect::new(830, 400, 75, 50), OBJ_DEFAULT_COLOR)?; + self.draw_rect(Rect::new(800, 400, 50, 50), OBJ_DEFAULT_COLOR)?; + self.draw_static_str("BAR", Rect::new(855, 400, 75, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("{:02x}", dp.bar()), + Rect::new(800, 400, 50, 50), + OBJ_DEFAULT_COLOR, + )?; + // Bar to SHam + self.draw_lines( + &[ + (810, 400, 810, 380), + (810, 380, 475, 380), + (475, 380, 475, 340), + (475, 340, 500, 340), + ], + OBJ_DEFAULT_COLOR, + )?; + // Busout + self.draw_lines( + &[ + (1050, 750, 1450, 750), + (1450, 750, 1450, 50), + (1050, 525, 1050, 750), + ], + OBJ_DEFAULT_COLOR, + )?; + self.draw_static_str("busOUT", Rect::new(1400, 750, 100, 50), OBJ_DEFAULT_COLOR)?; + // PADS (pins in/out) + self.draw_rect(Rect::new(1300, 25, 100, 100), OBJ_DEFAULT_COLOR)?; + self.draw_static_str("PADS", Rect::new(1300, 125, 100, 50), OBJ_DEFAULT_COLOR)?; + + // SDEC and SHAM + self.draw_rects( + &[Rect::new(550, 300, 150, 50), Rect::new(500, 300, 50, 50)], + OBJ_DEFAULT_COLOR, + )?; + self.draw_static_str("SHam", Rect::new(500, 250, 75, 50), OBJ_DEFAULT_COLOR)?; + self.draw_static_str("SDec", Rect::new(650, 250, 75, 50), OBJ_DEFAULT_COLOR)?; + self.draw_string( + &format!("{:02x}", dp.shifter().s_ham), + Rect::new(500, 300, 50, 50), + OBJ_DEFAULT_COLOR, + )?; + self.draw_string( + &format!("{:02x}", dp.shifter().s_dec), + Rect::new(600, 300, 50, 50), + OBJ_DEFAULT_COLOR, + )?; + // Connect SDec to Shifter + self.draw_line((600, 350, 700, 600), OBJ_DEFAULT_COLOR)?; // Draw the debug window. self.pane.canvas.present(); + Ok(()) } diff --git a/src/instruction.rs b/src/instruction.rs @@ -36,7 +36,7 @@ pub const SIGN_BIT_LOC: u32 = 0x80000000; // Enums and structs. -pub struct InstructionCycle([fn(dp: &mut DataPath); 4]); +pub struct InstructionCycle(pub [fn(dp: &mut DataPath); 5]); pub fn noop(dp: &mut DataPath) {} @@ -588,12 +588,12 @@ impl fmt::Display for Conditional { } impl InstructionCycle { - pub fn new(steps: [fn(dp: &mut DataPath); 4]) -> Self { + pub fn new(steps: [fn(dp: &mut DataPath); 5]) -> Self { Self { 0: steps } } pub fn noop_cycle() -> Self { - Self { 0: [noop; 4] } + Self { 0: [noop; 5] } } } diff --git a/src/shifter.rs b/src/shifter.rs @@ -23,6 +23,8 @@ pub struct Shifter { pub src: u32, /// Amount to shift the input. pub s_ham: u8, + /// Shift decoder value. Contains the amount to shift by. + pub s_dec: u8, } // Impls. @@ -30,7 +32,11 @@ pub struct Shifter { impl Shifter { /// Create a 0'd out shifter. pub fn new() -> Self { - Self { src: 0, s_ham: 0 } + Self { + src: 0, + s_ham: 0, + s_dec: 0, + } } /// Left shift `src` by `s_ham` bits. pub fn shift_left(&self) -> u32 { @@ -45,7 +51,7 @@ impl Shifter { impl fmt::Display for Shifter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}, {}", self.src, self.s_ham,) + write!(f, "{}, {}, {}", self.src, self.s_ham, self.s_dec) } } @@ -53,8 +59,8 @@ impl fmt::Debug for Shifter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "Input register: {}, SHam latch: {}", - self.src, self.s_ham, + "Input register: {}, SHam latch: {}, SDEC amount: {}", + self.src, self.s_ham, self.s_dec ) } } diff --git a/src/system.rs b/src/system.rs @@ -135,4 +135,16 @@ impl System { Phase::Interrupt => Phase::One, }; } + + pub fn clock(&self) -> &Clock { + &self.clock + } + + pub fn data_path(&self) -> &DataPath { + &self.data_path + } + + pub fn phase(&self) -> Phase { + self.phase.clone() + } }