From d49f82c800782082119dd87e9ae4dacc8b34524b Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:35:36 -0400 Subject: [PATCH 01/48] Display RISC-V stages on the visual datapath --- src/agent/datapath_reducer.rs | 7 +++++++ src/emulation_core/riscv/datapath.rs | 12 ++++++++++++ src/ui/visual_datapath/mod.rs | 10 ++-------- src/ui/visual_datapath/utils.rs | 2 ++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/agent/datapath_reducer.rs b/src/agent/datapath_reducer.rs index 04c4dd9b3..a47535967 100644 --- a/src/agent/datapath_reducer.rs +++ b/src/agent/datapath_reducer.rs @@ -159,4 +159,11 @@ impl DatapathReducer { RISCV => &self.riscv.memory, } } + + pub fn get_current_stage(&self) -> String { + match self.current_architecture { + MIPS => self.mips.current_stage.into(), + RISCV => self.riscv.current_stage.into(), + } + } } diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index bf145f799..8f7325d03 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -192,6 +192,18 @@ impl RiscStage { } } +impl From for String { + fn from(val: RiscStage) -> String { + String::from(match val { + RiscStage::InstructionFetch => "writeback", + RiscStage::InstructionDecode => "instruction_fetch", + RiscStage::Execute => "instruction_decode", + RiscStage::Memory => "execute", + RiscStage::WriteBack => "memory", + }) + } +} + impl Default for RiscDatapath { fn default() -> Self { let mut datapath = RiscDatapath { diff --git a/src/ui/visual_datapath/mod.rs b/src/ui/visual_datapath/mod.rs index 67ffb541d..e0117732a 100644 --- a/src/ui/visual_datapath/mod.rs +++ b/src/ui/visual_datapath/mod.rs @@ -36,7 +36,7 @@ use yew::prelude::*; use consts::*; use utils::*; -use crate::{agent::datapath_reducer::DatapathReducer, emulation_core::mips::datapath::Stage}; +use crate::agent::datapath_reducer::DatapathReducer; #[derive(PartialEq, Properties)] pub struct VisualDatapathProps { @@ -130,13 +130,7 @@ impl Component for VisualDatapath { // there is actual data to view. A better way to see this is "when stage X is // set on the datapath, highlight the lines for stage Y." The datapath stage // tells where it will start the next time "execute" is pressed. - let current_stage = String::from(match ctx.props().datapath_state.mips.current_stage { - Stage::InstructionFetch => "writeback", - Stage::InstructionDecode => "instruction_fetch", - Stage::Execute => "instruction_decode", - Stage::Memory => "execute", - Stage::WriteBack => "memory", - }); + let current_stage = ctx.props().datapath_state.get_current_stage(); debug!("Current stage: {:?}", current_stage); if first_render || self.should_reinitialize { diff --git a/src/ui/visual_datapath/utils.rs b/src/ui/visual_datapath/utils.rs index d265a7cd6..f9a1eded7 100644 --- a/src/ui/visual_datapath/utils.rs +++ b/src/ui/visual_datapath/utils.rs @@ -1,6 +1,7 @@ //! Helpful common functions used for the visual datapath. use gloo::utils::{document, window}; +use gloo_console::log; use wasm_bindgen::JsCast; use web_sys::{Element, HtmlCollection, HtmlElement, HtmlObjectElement, MouseEvent}; use yew::UseReducerHandle; @@ -181,6 +182,7 @@ pub fn visual_line_to_data( variable: &str, datapath_state: &UseReducerHandle, ) -> LineInformation { + log!("Calling here"); match datapath_state.current_architecture { AvailableDatapaths::MIPS => { match variable { From 818804dcd3050bce7bb0c984776acfd1ca924588 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:12:04 -0400 Subject: [PATCH 02/48] Fix visual datapath popup overflowing window --- src/bin/main.rs | 4 ++-- src/ui/visual_datapath/mod.rs | 2 +- src/ui/visual_datapath/utils.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index dee719dd2..a9f53a4ca 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -491,7 +491,7 @@ fn app(props: &AppProps) -> Html { log::debug!("{:?}", datapath_state.executing); html! { - <> +
// button tied to the input file element, which is hidden to be more clean
@@ -573,7 +573,7 @@ fn app(props: &AppProps) -> Html { // Right column
- +
} } diff --git a/src/ui/visual_datapath/mod.rs b/src/ui/visual_datapath/mod.rs index e0117732a..59a1e033e 100644 --- a/src/ui/visual_datapath/mod.rs +++ b/src/ui/visual_datapath/mod.rs @@ -84,7 +84,7 @@ impl Component for VisualDatapath { let zoom_out_size = Rc::clone(&self.size); html! {
-
+
- if **active_tab == FooterTabState::Datapath { + if **active_tab == FooterTabState::Datapath && props.datapath_state.current_architecture == MIPS {
diff --git a/src/ui/visual_datapath/mod.rs b/src/ui/visual_datapath/mod.rs index 59a1e033e..c2a3ab471 100644 --- a/src/ui/visual_datapath/mod.rs +++ b/src/ui/visual_datapath/mod.rs @@ -25,6 +25,7 @@ pub mod consts; pub mod utils; +use gloo_console::log; use std::{cell::RefCell, rc::Rc}; use gloo_events::EventListener; @@ -286,6 +287,8 @@ impl VisualDatapath { if let Ok(listeners) = Self::enable_interactivity(element, datapath_state, is_in_current_stage) { + log!("Found an element in the current stage!"); + log!(element.get_attribute("id")); for l in listeners { active_listeners.push(l); } @@ -366,7 +369,6 @@ impl VisualDatapath { } else { Self::set_inactive(&path)?; } - path.style().set_property("stroke-width", "10").unwrap(); if path.tag_name() == "path" { // Set the initial state of this path: diff --git a/static/datapath_riscv.svg b/static/datapath_riscv.svg index 0bcbba30f..3cb474d06 100644 --- a/static/datapath_riscv.svg +++ b/static/datapath_riscv.svg @@ -1,4 +1,3 @@ - -
Instruction [31-25] (funct7)
Instruction [14-12] (funct3)
ALUOp
OP2Select
PC
Instruction Memory
IMM Decode
ALU Control
Instruction [31-12] (imm)
Add
01S0
Mux
Branch
PC + 4
Control Unit
Instruction
WbSel
ReadWrite
Jump Address
Jump
Registers
Read Register 1
Read Register 2
Write Register
Write Data
Read Data 1
Read Data 2
Data Memory
Write Data
Address
Read Data
Instruction [11-7] (rd)
Instruction [24-20] (rs2)
Instruction Fetch
Instruction Decode / Register Read
Execute
Memory
Writeback
4
ALU
Zero
01S0
Mux
01S0
Mux
Mux012
Instruction [19-15] (rs1)
IMMSelect
RegWriteEn
Mux0123
Shift Left 2
Add
01S0
Mux
Shift Left 2
Branch
JumpSrc
OP1Select
\ No newline at end of file +
Instruction [31-25] (funct7)
Instruction [31-25] (funct7)
Instruction [14-12] (funct3)
Instruction [14-12] (funct3)
ALUOp
ALUOp
OP2Select
OP2Select
PC
PC
Instruction Memory
Instruction Memory
IMM Decode
IMM Decode
ALU Control
ALU Control
Instruction [31-12] (imm)
Instruction [31-12] (imm)
Add
Add
01S0
Mux
Mux
Branch
Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
WbSel
WbSel
ReadWrite
ReadWrite
Jump Address
Jump Address
Jump
Jump
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [11-7] (rd)
Instruction [11-7] (rd)
Instruction [24-20] (rs2)
Instruction [24-20] (rs2)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
Mux012
Instruction [19-15] (rs1)
Instruction [19-15] (rs1)
IMMSelect
IMMSelect
RegWriteEn
RegWriteEn
Mux0123
Shift Left 2
Shift Left 2
Add
Add
01S0
Mux
Mux
Shift Left 2
Shift Left 2
Branch
Branch
JumpSrc
JumpSrc
OP1Select
OP1Select
Text is not SVG - cannot display
\ No newline at end of file From 66e5a8cc509bb08407a7a79629a510c56739add9 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:36:38 -0400 Subject: [PATCH 27/48] Fatten up the MIPS datapaths --- media/datapath-full.drawio | 228 +++++++++++++++++------------------ media/datapath-simple.drawio | 109 +++++++++-------- src/ui/footer/component.rs | 2 +- static/datapath_full.svg | 3 +- static/datapath_simple.svg | 3 +- 5 files changed, 173 insertions(+), 172 deletions(-) diff --git a/media/datapath-full.drawio b/media/datapath-full.drawio index 9b9e89f2e..2f6572d75 100644 --- a/media/datapath-full.drawio +++ b/media/datapath-full.drawio @@ -1,9 +1,24 @@ - + - + + + + + + + + + + + + + + + + @@ -20,7 +35,7 @@ - + @@ -110,7 +125,7 @@ - + @@ -174,7 +189,7 @@ - + @@ -182,7 +197,7 @@ - + @@ -190,7 +205,7 @@ - + @@ -207,7 +222,7 @@ - + @@ -217,16 +232,11 @@ - - - - - - + @@ -235,7 +245,7 @@ - + @@ -243,7 +253,7 @@ - + @@ -252,7 +262,7 @@ - + @@ -263,7 +273,7 @@ - + @@ -283,7 +293,7 @@ - + @@ -291,7 +301,7 @@ - + @@ -299,7 +309,7 @@ - + @@ -319,7 +329,7 @@ - + @@ -327,7 +337,7 @@ - + @@ -338,7 +348,7 @@ - + @@ -358,13 +368,8 @@ - - - - - - + @@ -372,7 +377,7 @@ - + @@ -383,7 +388,7 @@ - + @@ -398,7 +403,7 @@ - + @@ -409,7 +414,7 @@ - + @@ -431,7 +436,7 @@ - + @@ -439,7 +444,7 @@ - + @@ -478,7 +483,7 @@ - + @@ -499,7 +504,7 @@ - + @@ -605,7 +610,7 @@ - + @@ -616,7 +621,7 @@ - + @@ -640,7 +645,7 @@ - + @@ -654,7 +659,7 @@ - + @@ -672,7 +677,7 @@ - + @@ -700,7 +705,7 @@ - + @@ -708,7 +713,7 @@ - + @@ -793,7 +798,7 @@ - + @@ -808,7 +813,7 @@ - + @@ -816,7 +821,7 @@ - + @@ -826,7 +831,7 @@ - + @@ -834,7 +839,7 @@ - + @@ -849,7 +854,7 @@ - + @@ -865,7 +870,7 @@ - + @@ -960,7 +965,7 @@ - + @@ -973,12 +978,12 @@ - + - + @@ -995,7 +1000,7 @@ - + @@ -1005,7 +1010,7 @@ - + @@ -1018,7 +1023,7 @@ - + @@ -1031,7 +1036,7 @@ - + @@ -1059,7 +1064,7 @@ - + @@ -1075,7 +1080,7 @@ - + @@ -1095,7 +1100,7 @@ - + @@ -1110,7 +1115,7 @@ - + @@ -1118,7 +1123,7 @@ - + @@ -1134,7 +1139,7 @@ - + @@ -1156,7 +1161,7 @@ - + @@ -1185,7 +1190,7 @@ - + @@ -1193,7 +1198,7 @@ - + @@ -1209,7 +1214,7 @@ - + @@ -1218,7 +1223,7 @@ - + @@ -1246,7 +1251,7 @@ - + @@ -1262,7 +1267,7 @@ - + @@ -1274,7 +1279,7 @@ - + @@ -1309,7 +1314,7 @@ - + @@ -1317,7 +1322,7 @@ - + @@ -1334,7 +1339,7 @@ - + @@ -1347,7 +1352,7 @@ - + @@ -1355,7 +1360,7 @@ - + @@ -1369,7 +1374,7 @@ - + @@ -1397,7 +1402,7 @@ - + @@ -1412,7 +1417,7 @@ - + @@ -1420,7 +1425,7 @@ - + @@ -1433,7 +1438,7 @@ - + @@ -1447,7 +1452,7 @@ - + @@ -1455,7 +1460,7 @@ - + @@ -1472,7 +1477,7 @@ - + @@ -1516,7 +1521,7 @@ - + @@ -1532,7 +1537,7 @@ - + @@ -1546,7 +1551,7 @@ - + @@ -1563,7 +1568,7 @@ - + @@ -1575,7 +1580,7 @@ - + @@ -1589,7 +1594,7 @@ - + @@ -1604,7 +1609,7 @@ - + @@ -1621,7 +1626,7 @@ - + @@ -1663,7 +1668,7 @@ - + @@ -1679,7 +1684,7 @@ - + @@ -1795,7 +1800,7 @@ - + @@ -1809,7 +1814,7 @@ - + @@ -1817,7 +1822,7 @@ - + @@ -1879,7 +1884,7 @@ - + @@ -1915,7 +1920,7 @@ - + @@ -1927,22 +1932,17 @@ - + - + - - - - - - + @@ -1960,7 +1960,7 @@ - + @@ -1971,7 +1971,7 @@ - + @@ -1990,7 +1990,7 @@ - + @@ -2006,7 +2006,7 @@ - + @@ -2024,7 +2024,7 @@ - + diff --git a/media/datapath-simple.drawio b/media/datapath-simple.drawio index ca5307789..dc0364d1f 100644 --- a/media/datapath-simple.drawio +++ b/media/datapath-simple.drawio @@ -1,9 +1,19 @@ - + - + + + + + + + + + + + @@ -47,7 +57,7 @@ - + @@ -80,13 +90,16 @@ + + + - + @@ -94,7 +107,7 @@ - + @@ -102,7 +115,7 @@ - + @@ -119,7 +132,7 @@ - + @@ -142,7 +155,7 @@ - + @@ -161,7 +174,7 @@ - + @@ -175,7 +188,7 @@ - + @@ -183,7 +196,7 @@ - + @@ -196,7 +209,7 @@ - + @@ -207,7 +220,7 @@ - + @@ -225,7 +238,7 @@ - + @@ -235,7 +248,7 @@ - + @@ -261,13 +274,8 @@ - - - - - - + @@ -275,7 +283,7 @@ - + @@ -287,7 +295,7 @@ - + @@ -302,7 +310,7 @@ - + @@ -313,7 +321,7 @@ - + @@ -335,7 +343,7 @@ - + @@ -343,7 +351,7 @@ - + @@ -364,7 +372,7 @@ - + @@ -385,7 +393,7 @@ - + @@ -486,7 +494,7 @@ - + @@ -508,7 +516,7 @@ - + @@ -522,7 +530,7 @@ - + @@ -539,7 +547,7 @@ - + @@ -569,7 +577,7 @@ - + @@ -577,7 +585,7 @@ - + @@ -632,7 +640,7 @@ - + @@ -645,7 +653,7 @@ - + @@ -659,7 +667,7 @@ - + @@ -673,7 +681,7 @@ - + @@ -689,7 +697,7 @@ - + @@ -701,7 +709,7 @@ - + @@ -715,7 +723,7 @@ - + @@ -726,7 +734,7 @@ - + @@ -777,7 +785,7 @@ - + @@ -824,7 +832,7 @@ - + @@ -836,7 +844,7 @@ - + @@ -862,13 +870,8 @@ - - - - - - + @@ -884,7 +887,7 @@ - + diff --git a/src/ui/footer/component.rs b/src/ui/footer/component.rs index 5ba72247d..68c9baa02 100644 --- a/src/ui/footer/component.rs +++ b/src/ui/footer/component.rs @@ -64,7 +64,7 @@ pub fn footer(props: &Footerprops) -> Html { let svg_path = match props.datapath_state.current_architecture { MIPS => match *switch_datapath { true => "static/datapath_full.svg", - false => "static/datapath_riscv.svg", + false => "static/datapath_simple.svg", }, RISCV => "static/datapath_riscv.svg", }; diff --git a/static/datapath_full.svg b/static/datapath_full.svg index 280bad613..b6efe2728 100644 --- a/static/datapath_full.svg +++ b/static/datapath_full.svg @@ -1,4 +1,3 @@ - -
ImmShift
ImmShift
ALUOp
ALUOp
ALUSrc
ALUSrc
MemWriteSrc
MemWriteSrc
FpuRegDst
FpuRegDst
RegDst
RegDst
PC
PC
Instruction Memory
Instruction Memory
Sign-Extend
Sign-Extend
Shift Left 2
Shift Left 2
ALU Control
ALU Control
Add
Add
Add
Add
01S0
Mux
Mux
Relative PC Branch
Relative PC Branch
PC + 4
PC + 4
BranchType
BranchType
Control Unit
Control Unit
Instruction
Instruction
Branch
Branch
MemRead
MemRead
MemToReg
MemToReg
MemWrite
MemWrite
RegWrite
RegWrite
Shift Left 2
Shift Left 2
Jump Address
Jump Address
Jump
Jump
PC + 4 [63-28]
PC + 4 [63-28]
Floating Point Unit (Coprocessor 1)
Floating Point Unit (Coprocessor 1)
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Floating Point Registers
Floating Point Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Format
Format
Instruction [15-11] (fs)
Instruction [15-11] (fs)
Instruction [25-21] (fmt)
Instruction [25-21] (fmt)
FpuRegWrite
FpuRegWrite
CCWrite
CCWrite
DataSrc
DataSrc
CC
CC
FpuBranch
FpuBranch
FpuMemToReg
FpuMemToReg
FPU Control Unit
FPU Control Unit
FP
Comparator
FP...
Zero
Zero
ALU Result
ALU Result
Condition Code Register
Condition Cod...
Instruction [31-0]
Instruction [31-0]
FpuALUOp
FpuALUOp
FP ALU
FP ALU
Zero
Zero
ALU Result
ALU Result
DataWrite
DataWrite
Data
Data
01S0
Mux
Mux
Sign-Extend
Sign-Ext...
01S0
Mux
Mux
Instruction [10-6] (fd)
Instruction [10-6] (fd)
01S0
Mux
Mux
Instruction [16] (branch if true/false flag)
Instruction [16] (branch if true/false flag)
01S0
Mux
Mux
01S0
Mux
Mux
01S0
Mux
Mux
RegWidth
RegWidth
FpuRegWidth
FpuRegWidth
Instruction [25-21] (rs or base)
Instruction [25-21] (rs or base)
Instruction [15-11] (rd)
Instruction [15-11] (rd)
Instruction [20-16] (rt)
Instruction [20-16] (rt)
<<
<<
Mux012
Zero-extended immediate
Zero-extended immediate
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
Instruction [20-16] (ft)
Instruction [20-16] (ft)
01S0
Mux
Mux
[31-0]
[31-0]
01S0
Mux
Mux
Mux210
4
4
ALU
ALU
Zero
Zero
Mux012
Instruction [10-6] (fd)
Instruction [10-6] (fd)
Mux0123
31
31
Instruction [10-6] (shamt)
Instruction [10-6] (shamt)
Mux210
Instruction [25-0]
Instruction [25-0]
Instruction [5-0] (funct)
Instruction [5-0] (funct)
Text is not SVG - cannot display
\ No newline at end of file +
ImmShift
ImmShift
ALUOp
ALUOp
ALUSrc
ALUSrc
MemWriteSrc
MemWriteSrc
FpuRegDst
FpuRegDst
RegDst
RegDst
PC
PC
Instruction Memory
Instruction Memory
Sign-Extend
Sign-Extend
Shift Left 2
Shift Left 2
ALU Control
ALU Control
Add
Add
Add
Add
01S0
Mux
Mux
Relative PC Branch
Relative PC Branch
PC + 4
PC + 4
BranchType
BranchType
Control Unit
Control Unit
Instruction
Instruction
Branch
Branch
MemRead
MemRead
MemToReg
MemToReg
MemWrite
MemWrite
RegWrite
RegWrite
Shift Left 2
Shift Left 2
Jump Address
Jump Address
Jump
Jump
PC + 4 [63-28]
PC + 4 [63-28]
Floating Point Unit (Coprocessor 1)
Floating Point Unit (Coprocessor 1)
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Floating Point Registers
Floating Point Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Format
Format
Instruction [15-11] (fs)
Instruction [15-11] (fs)
Instruction [25-21] (fmt)
Instruction [25-21] (fmt)
FpuRegWrite
FpuRegWrite
CCWrite
CCWrite
DataSrc
DataSrc
CC
CC
FpuBranch
FpuBranch
FpuMemToReg
FpuMemToReg
FPU Control Unit
FPU Control Unit
FP
Comparator
FP...
Zero
Zero
ALU Result
ALU Result
Condition Code Register
Condition Cod...
Instruction [31-0]
Instruction [31-0]
FpuALUOp
FpuALUOp
FP ALU
FP ALU
Zero
Zero
ALU Result
ALU Result
DataWrite
DataWrite
Data
Data
01S0
Mux
Mux
Sign-Extend
Sign-Ext...
01S0
Mux
Mux
Instruction [10-6] (fd)
Instruction [10-6] (fd)
01S0
Mux
Mux
Instruction [16] (branch if true/false flag)
Instruction [16] (branch if true/false flag)
01S0
Mux
Mux
01S0
Mux
Mux
01S0
Mux
Mux
RegWidth
RegWidth
FpuRegWidth
FpuRegWidth
Instruction [25-21] (rs or base)
Instruction [25-21] (rs or base)
Instruction [15-11] (rd)
Instruction [15-11] (rd)
Instruction [20-16] (rt)
Instruction [20-16] (rt)
<<
<<
Mux012
Zero-extended immediate
Zero-extended immediate
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
Instruction [20-16] (ft)
Instruction [20-16] (ft)
01S0
Mux
Mux
[31-0]
[31-0]
01S0
Mux
Mux
Mux210
4
4
ALU
ALU
Zero
Zero
Mux012
Instruction [10-6] (fd)
Instruction [10-6] (fd)
Mux0123
31
31
Instruction [10-6] (shamt)
Instruction [10-6] (shamt)
Mux210
Instruction [25-0]
Instruction [25-0]
Instruction [5-0] (funct)
Instruction [5-0] (funct)
Text is not SVG - cannot display
\ No newline at end of file diff --git a/static/datapath_simple.svg b/static/datapath_simple.svg index 8ef5a51a1..65dfdbae4 100644 --- a/static/datapath_simple.svg +++ b/static/datapath_simple.svg @@ -1,4 +1,3 @@ - -
ALUOp
ALUOp
ALUSrc
ALUSrc
RegDst
RegDst
PC
PC
Instruction Memory
Instruction Memory
Sign-Extend
Sign-Extend
Shift Left 2
Shift Left 2
ALU Control
ALU Control
Instruction [5-0] (funct)
Instruction [5-0] (funct)
Instruction [15-0] (imm)
Instruction [15-0] (imm)
Add
Add
Add
Add
01S0
Mux
Mux
Relative PC Branch
Relative PC Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
Branch
Branch
MemRead
MemRead
MemToReg
MemToReg
MemWrite
MemWrite
RegWrite
RegWrite
Shift Left 2
Shift Left 2
Jump Address
Jump Address
Jump
Jump
PC + 4 [63-28]
PC + 4 [63-28]
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [25-21] (rs or base)
Instruction [25-21] (rs or base)
Instruction [15-11] (rd)
Instruction [15-11] (rd)
Instruction [20-16] (rt)
Instruction [20-16] (rt)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
01S0
Mux
Mux
01S0
Mux
Mux
Instruction [25-0]
Instruction [25-0]
Text is not SVG - cannot display
\ No newline at end of file +
ALUOp
ALUOp
ALUSrc
ALUSrc
RegDst
RegDst
PC
PC
Instruction Memory
Instruction Memory
Sign-Extend
Sign-Extend
Shift Left 2
Shift Left 2
ALU Control
ALU Control
Instruction [5-0] (funct)
Instruction [5-0] (funct)
Instruction [15-0] (imm)
Instruction [15-0] (imm)
Add
Add
Add
Add
01S0
Mux
Mux
Relative PC Branch
Relative PC Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
Branch
Branch
MemRead
MemRead
MemToReg
MemToReg
MemWrite
MemWrite
RegWrite
RegWrite
Shift Left 2
Shift Left 2
Jump Address
Jump Address
Jump
Jump
PC + 4 [63-28]
PC + 4 [63-28]
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [25-21] (rs or base)
Instruction [25-21] (rs or base)
Instruction [15-11] (rd)
Instruction [15-11] (rd)
Instruction [20-16] (rt)
Instruction [20-16] (rt)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
01S0
Mux
Mux
01S0
Mux
Mux
Instruction [25-0]
Instruction [25-0]
Text is not SVG - cannot display
\ No newline at end of file From ab06eff134e778cfde71fdd74e40fb4471556393 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:54:29 -0400 Subject: [PATCH 28/48] Fix up some visual issues with the RISC-V datapath --- media/datapath-riscv.drawio | 89 +++++++++++++++++------------------ src/ui/footer/component.rs | 1 - src/ui/visual_datapath/mod.rs | 2 - static/datapath_riscv.svg | 2 +- 4 files changed, 45 insertions(+), 49 deletions(-) diff --git a/media/datapath-riscv.drawio b/media/datapath-riscv.drawio index edf78be1f..3406a6495 100644 --- a/media/datapath-riscv.drawio +++ b/media/datapath-riscv.drawio @@ -1,9 +1,14 @@ - + - + + + + + + @@ -15,7 +20,7 @@ - + @@ -106,7 +111,9 @@ - + + + @@ -297,7 +304,7 @@
- + @@ -429,7 +436,7 @@ - + @@ -695,18 +702,6 @@ - - - - - - - - - - - - @@ -786,13 +781,15 @@ - - - - - - - + + + + + + + + + @@ -861,12 +858,14 @@ - - - - - - + + + + + + + + @@ -938,17 +937,17 @@ - + - + - + - + @@ -957,12 +956,12 @@ - + - + @@ -970,7 +969,7 @@ - + @@ -981,12 +980,12 @@ - + - + @@ -1022,12 +1021,12 @@ - + - + @@ -1039,7 +1038,7 @@ - + @@ -1050,7 +1049,7 @@ - + @@ -1059,7 +1058,7 @@ - + diff --git a/src/ui/footer/component.rs b/src/ui/footer/component.rs index 68c9baa02..d3980865d 100644 --- a/src/ui/footer/component.rs +++ b/src/ui/footer/component.rs @@ -1,6 +1,5 @@ use crate::agent::datapath_communicator::DatapathCommunicator; use crate::agent::datapath_reducer::DatapathReducer; -use crate::emulation_core::architectures::AvailableDatapaths; use crate::emulation_core::architectures::AvailableDatapaths::{MIPS, RISCV}; use crate::ui::console::component::Console; use crate::ui::hex_editor::component::HexEditor; diff --git a/src/ui/visual_datapath/mod.rs b/src/ui/visual_datapath/mod.rs index c2a3ab471..17e3e97b6 100644 --- a/src/ui/visual_datapath/mod.rs +++ b/src/ui/visual_datapath/mod.rs @@ -287,8 +287,6 @@ impl VisualDatapath { if let Ok(listeners) = Self::enable_interactivity(element, datapath_state, is_in_current_stage) { - log!("Found an element in the current stage!"); - log!(element.get_attribute("id")); for l in listeners { active_listeners.push(l); } diff --git a/static/datapath_riscv.svg b/static/datapath_riscv.svg index 3cb474d06..02f1d3f2d 100644 --- a/static/datapath_riscv.svg +++ b/static/datapath_riscv.svg @@ -1,3 +1,3 @@ -
Instruction [31-25] (funct7)
Instruction [31-25] (funct7)
Instruction [14-12] (funct3)
Instruction [14-12] (funct3)
ALUOp
ALUOp
OP2Select
OP2Select
PC
PC
Instruction Memory
Instruction Memory
IMM Decode
IMM Decode
ALU Control
ALU Control
Instruction [31-12] (imm)
Instruction [31-12] (imm)
Add
Add
01S0
Mux
Mux
Branch
Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
WbSel
WbSel
ReadWrite
ReadWrite
Jump Address
Jump Address
Jump
Jump
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [11-7] (rd)
Instruction [11-7] (rd)
Instruction [24-20] (rs2)
Instruction [24-20] (rs2)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
Mux012
Instruction [19-15] (rs1)
Instruction [19-15] (rs1)
IMMSelect
IMMSelect
RegWriteEn
RegWriteEn
Mux0123
Shift Left 2
Shift Left 2
Add
Add
01S0
Mux
Mux
Shift Left 2
Shift Left 2
Branch
Branch
JumpSrc
JumpSrc
OP1Select
OP1Select
Text is not SVG - cannot display
\ No newline at end of file +
Instruction [31-25] (funct7)
Instruction [31-25] (funct7)
Instruction [14-12] (funct3)
Instruction [14-12] (funct3)
ALUOp
ALUOp
OP2Select
OP2Select
PC
PC
Instruction Memory
Instruction Memory
IMM Decode
IMM Decode
ALU Control
ALU Control
Instruction [31-12] (imm)
Instruction [31-12] (imm)
Add
Add
01S0
Mux
Mux
Branch
Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
WbSel
WbSel
ReadWrite
ReadWrite
Jump Address
Jump Address
Jump
Jump
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [11-7] (rd)
Instruction [11-7] (rd)
Instruction [24-20] (rs2)
Instruction [24-20] (rs2)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
Mux012
Instruction [19-15] (rs1)
Instruction [19-15] (rs1)
IMMSelect
IMMSelect
RegWriteEn
RegWriteEn
Mux0123
Shift Left 2
Shift Left 2
Add
Add
01S0
Mux
Mux
Shift Left 2
Shift Left 2
Branch
Branch
JumpSrc
JumpSrc
OP1Select
OP1Select
Text is not SVG - cannot display
\ No newline at end of file From e049880712174ada70aa1b365be2caa13da02b8a Mon Sep 17 00:00:00 2001 From: rharding8 Date: Thu, 28 Mar 2024 23:10:46 -0400 Subject: [PATCH 29/48] Fixed issues. Every instruction aside from FLW is working correctly. --- src/emulation_core/riscv/coprocessor.rs | 66 +++++++++++-------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/src/emulation_core/riscv/coprocessor.rs b/src/emulation_core/riscv/coprocessor.rs index 6d73cf351..d1bd8ecde 100644 --- a/src/emulation_core/riscv/coprocessor.rs +++ b/src/emulation_core/riscv/coprocessor.rs @@ -2,8 +2,7 @@ use std::ops::Neg; -use super::constants::{OPCODE_MADD, OPCODE_MSUB, OPCODE_NMADD, OPCODE_NMSUB}; -// use super::constants::*; +use super::constants::*; use super::instruction::Instruction; use super::registers::FpRegisters; use super::{constants::RISC_NAN, control_signals::floating_point::*}; @@ -206,11 +205,16 @@ impl RiscFpCoprocessor { self.signals = FpuControlSignals { data_write: DataWrite::NoWrite, fpu_mem_to_reg: FpuMemToReg::UseDataWrite, - fpu_reg_dst: FpuRegDst::Reg3, fpu_reg_write: FpuRegWrite::YesWrite, + fpu_reg_dst: FpuRegDst::Reg3, ..Default::default() }; + if r.op != OPCODE_OP_FP { + self.signals.fpu_reg_write = FpuRegWrite::NoWrite; + return; + } + match r.funct7 >> 2 { 0 => self.signals.fpu_alu_op = FpuAluOp::Addition, 1 => self.signals.fpu_alu_op = FpuAluOp::Subtraction, @@ -272,13 +276,17 @@ impl RiscFpCoprocessor { _ => self.error("Unsupported Rounding Mode!"), } } - Instruction::IType(_i) => { + Instruction::IType(i) => { self.signals = FpuControlSignals { data_write: DataWrite::NoWrite, fpu_mem_to_reg: FpuMemToReg::UseMemory, fpu_reg_dst: FpuRegDst::Reg3, fpu_reg_write: FpuRegWrite::YesWrite, ..Default::default() + }; + + if i.op != OPCODE_LOAD_FP { + self.signals.fpu_reg_write = FpuRegWrite::NoWrite; } } Instruction::SType(_s) => { @@ -286,7 +294,7 @@ impl RiscFpCoprocessor { data_write: DataWrite::NoWrite, fpu_reg_write: FpuRegWrite::NoWrite, ..Default::default() - } + }; } Instruction::R4Type(r4) => { self.signals = FpuControlSignals { @@ -437,13 +445,7 @@ impl RiscFpCoprocessor { RoundingMode::RDN => f32::to_bits(result_f32.floor()) as u64, RoundingMode::RUP => f32::to_bits(result_f32.ceil()) as u64, RoundingMode::RMM => f32::to_bits(result_f32.round()) as u64, - _ => { - self.error(&format!( - "Unsupported operation in FPU `{:?}`", - self.signals.fpu_alu_op - )); - 0 - } + _ => f32::to_bits(result_f32) as u64, }; } @@ -458,14 +460,7 @@ impl RiscFpCoprocessor { FpuAluOp::MultiplicationOrEqual => (input1_f32 == input2_f32) as u64, FpuAluOp::Slt => (input1_f32 < input2_f32) as u64, FpuAluOp::Sle => (input1_f32 <= input2_f32) as u64, - FpuAluOp::Addition | FpuAluOp::Subtraction | FpuAluOp::Division => 0, // No operation - _ => { - self.error(&format!( - "Unsupported operation in comparator `{:?}`", - self.signals.fpu_alu_op - )); - 0 - } + _ => 0, } } @@ -488,13 +483,17 @@ impl RiscFpCoprocessor { /// Set the data line that goes from `Read Data 1` to the multiplexer in the main processor /// controlled by [`MemWriteSrc`](super::control_signals::MemWriteSrc). fn write_fp_register_to_memory(&mut self) { - self.state.fp_register_to_memory = self.state.read_data_1; + self.state.fp_register_to_memory = f32::from_bits(self.state.read_data_2 as u32) as u64; } // ======================= Memory (MEM) ======================= /// Set the data line between the multiplexer after the `Data` register and the /// multiplexer in the main processor controlled by the [`DataWrite`] control signal. fn set_data_writeback(&mut self) { + if let DataWrite::NoWrite = self.signals.data_write { + return; + } + self.state.data_writeback = match self.signals.data_src { DataSrc::MainProcessorUnit => match self.state.rs2 { 0 => f32::to_bits(self.data as i32 as f32) as u64, @@ -528,27 +527,20 @@ impl RiscFpCoprocessor { RoundingMode::RTZ => data_unrounded.trunc(), RoundingMode::RDN => data_unrounded.floor(), RoundingMode::RUP => data_unrounded.ceil(), - RoundingMode::RMM => data_unrounded.round(), - _ => { - self.error(&format!( - "Unsupported Rounding Mode `{:?}`", - self.signals.round_mode - )); - 0.0 - } + _ => data_unrounded.round(), }; match self.state.rs2 { 0 => { - if (data_rounded <= (-(2_i32.pow(31))) as f32) + if (data_rounded <= (-(2_i64.pow(31))) as f32) | (data_rounded == f32::NEG_INFINITY) { - -(2_i32.pow(31)) as u64 - } else if (data_rounded >= (2_i32.pow(31) - 1) as f32) + -(2_i64.pow(31)) as u64 + } else if (data_rounded >= (2_i64.pow(31) - 1) as f32) | (data_rounded == f32::INFINITY) | (data_rounded.is_nan()) { - (2_i32.pow(31) - 1) as u64 + (2_i64.pow(31) - 1) as u64 } else { data_rounded as i32 as u64 } @@ -556,11 +548,11 @@ impl RiscFpCoprocessor { 1 => { if (data_rounded <= 0.0) | (data_rounded == f32::NEG_INFINITY) { 0 - } else if (data_rounded >= (2_u32.pow(32) - 1) as f32) + } else if (data_rounded >= (2_u64.pow(32) - 1) as f32) | (data_rounded == f32::INFINITY) | (data_rounded.is_nan()) { - (2_u32.pow(32) - 1) as u64 + 2_u64.pow(32) - 1 } else { data_rounded as u32 as u64 } @@ -582,11 +574,11 @@ impl RiscFpCoprocessor { 3 => { if (data_rounded <= 0.0) | (data_rounded == f32::NEG_INFINITY) { 0 - } else if (data_rounded >= (2_u64.pow(64) - 1) as f32) + } else if (data_rounded >= (0x1111111111111111_i64) as f32) | (data_rounded == f32::INFINITY) | (data_rounded.is_nan()) { - 2_u64.pow(64) - 1 + 0x1111111111111111 } else { data_rounded as u64 } From f81a8404c4d01cfa48951361ad621481424a7a03 Mon Sep 17 00:00:00 2001 From: rharding8 Date: Thu, 28 Mar 2024 23:14:17 -0400 Subject: [PATCH 30/48] One instruction was wrong. Fixed now. --- src/emulation_core/riscv/coprocessor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emulation_core/riscv/coprocessor.rs b/src/emulation_core/riscv/coprocessor.rs index d1bd8ecde..cc12133d9 100644 --- a/src/emulation_core/riscv/coprocessor.rs +++ b/src/emulation_core/riscv/coprocessor.rs @@ -483,7 +483,7 @@ impl RiscFpCoprocessor { /// Set the data line that goes from `Read Data 1` to the multiplexer in the main processor /// controlled by [`MemWriteSrc`](super::control_signals::MemWriteSrc). fn write_fp_register_to_memory(&mut self) { - self.state.fp_register_to_memory = f32::from_bits(self.state.read_data_2 as u32) as u64; + self.state.fp_register_to_memory = self.state.read_data_2; } // ======================= Memory (MEM) ======================= From dcf96c5dc3fb2b9817091d33293d492be94a7d7e Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Thu, 28 Mar 2024 23:58:43 -0400 Subject: [PATCH 31/48] Fix RISC-V visual datapath displaying information from the MIPS core --- media/datapath-riscv.drawio | 22 +- src/emulation_core/riscv/datapath.rs | 1 + src/ui/visual_datapath/utils.rs | 521 +++++++++++---------------- static/datapath_riscv.svg | 2 +- 4 files changed, 213 insertions(+), 333 deletions(-) diff --git a/media/datapath-riscv.drawio b/media/datapath-riscv.drawio index 3406a6495..c38e2ee7e 100644 --- a/media/datapath-riscv.drawio +++ b/media/datapath-riscv.drawio @@ -1,6 +1,6 @@ - + - + @@ -120,7 +120,7 @@ - + @@ -576,20 +576,8 @@ - - - - - - - - - - - - - + @@ -599,7 +587,7 @@ - + diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index dd65a7af9..7aa10b6c1 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -56,6 +56,7 @@ use super::{super::mips::memory::Memory, registers::RiscGpRegisters}; use crate::emulation_core::architectures::DatapathRef; use crate::emulation_core::datapath::{DatapathUpdateSignal, Syscall}; use crate::emulation_core::riscv::registers::GpRegisterType::{X10, X11}; +use gloo_console::log; use serde::{Deserialize, Serialize}; /// An implementation of a datapath for the MIPS64 ISA. diff --git a/src/ui/visual_datapath/utils.rs b/src/ui/visual_datapath/utils.rs index 522d833b5..6ed40001a 100644 --- a/src/ui/visual_datapath/utils.rs +++ b/src/ui/visual_datapath/utils.rs @@ -350,7 +350,7 @@ pub fn visual_line_to_data( }, "jump_address" => LineInformation { title: String::from("Jump Address"), - description: String::from("The concatenation of the upper 36 bits of PC + 4 with the lower 26 bits of the instruction, shifted left by 2. This is used as the new PC value for J-type instructions."), + description: String::from("The calculated next program counter for jump instructions. For I type instructions, this is the immediate value added to the data in rs1. For U type instructions, this is the immediate value shifted left by 2."), value: datapath_state.mips.state.jump_address, bits: 64, }, @@ -495,321 +495,212 @@ pub fn visual_line_to_data( } }, AvailableDatapaths::RISCV => { - // just a stand in - LineInformation { - title: String::from("ALU Input 2"), - description: String::from("The second input to the ALU. This is determined by the ALUSrc control signal to select between register data, a sign-extended and left-shifted immediate value, or a zero-extended immediate value."), - value: datapath_state.mips.state.alu_input2, - bits: 64 + match variable { + "alu_input1" => LineInformation { + title: String::from("ALU Input 1"), + description: String::from("The first input to the ALU. This is determined by the OP1Select control signal to select between the current program counter, a sign-extended and left-shifted immediate value, or the data from rs1."), + value: datapath_state.riscv.state.alu_input1, + bits: 64, + }, + "alu_input2" => LineInformation { + title: String::from("ALU Input 2"), + description: String::from("The second input to the ALU. This is determined by the ALUSrc control signal to select between register data and a sign-extended and left-shifted immediate value."), + value: datapath_state.riscv.state.alu_input2, + bits: 64, + }, + "alu_result" => LineInformation { + title: String::from("ALU Result"), + description: String::from("The result of the calculation performed by the ALU. This is used either as an address to access memory or as a value that is saved into a register."), + value: datapath_state.riscv.state.alu_result, + bits: 64, + }, + "data_result" => LineInformation { + title: String::from("Writeback Data"), + description: String::from("After finishing processing the instruction, this will either be the ALU result, data from memory, or PC + 4, based on the MemToReg control signal. This data is saved into registers."), + value: datapath_state.riscv.state.data_result, + bits: 64, + }, + "funct3" => LineInformation { + title: String::from("Instruction [14-12] (funct)"), + description: String::from("The funct3 field. Controls the type of operation to execute for all RISC-V instructions except for U and J type instructions."), + value: datapath_state.riscv.state.funct3 as u64, + bits: 3, + }, + "funct7" => LineInformation { + title: String::from("Instruction [31-25] (funct7)"), + description: String::from("The funct7 field. Controls the type of operation to execute for R type instructions."), + value: datapath_state.riscv.state.funct7 as u64, + bits: 7, + }, + "imm" => LineInformation { + title: String::from("Immediate"), + description: String::from("The immediate field. This field is a different size depending on the instruction type, but it can be at most 20 bits."), + value: datapath_state.riscv.state.imm as u64, + bits: 20, + }, + "imm_input" => LineInformation { + title: String::from("Instruction [31-12] (immediate)"), + description: String::from("The part of the instruction used to extract the imm field from an instruction. In RISC-V, depending on the instruction type, the imm field can be split up within an instruction (S, B, and J type) or even out of order (B and J type)."), + value: 0u64, // FIXME: Use the real line + bits: 20, + }, + "instruction" => LineInformation { + title: String::from("Instruction"), + description: String::from("The currently-loaded instruction. This is broken down into different fields, where each field serves a different purpose in identifying what the instruction does."), + value: datapath_state.riscv.state.instruction as u64, + bits: 32, + }, + "i_type_address" => LineInformation { + title: String::from("I type jump address"), + description: String::from("The jump address used for I type instructions. Calculated from the data in rs1 and imm."), + value: 0u64, // FIXME: Use the real line + bits: 16, + }, + "jump_address" => LineInformation { + title: String::from("Jump Address"), + description: String::from("The calculated next program counter for jump instructions. For I type instructions, this is the immediate value added to the data in rs1. For U type instructions, this is the immediate value shifted left by 2."), + value: datapath_state.riscv.state.jump_address, + bits: 64, + }, + "lower_26" => LineInformation { + title: String::from("Instruction [25-0]"), + description: String::from("The lower 26 bits of instruction. This is used as part of the new PC value for J-type instructions."), + value: datapath_state.riscv.state.lower_26 as u64, + bits: 26, + }, + "lower_26_shifted_left_by_2" => LineInformation { + title: String::from("Instruction [25-0] << 2"), + description: String::from("The lower 26 bits of instruction, shifted left by 2. This is used as part of the new PC value for J-type instructions."), + value: datapath_state.riscv.state.lower_26_shifted_left_by_2 as u64, + bits: 28, + }, + "mem_mux1_to_mem_mux2" => LineInformation { + title: String::from("Relative PC Address"), + description: String::from("Based on the control signals for branching and jumping, this address may be the next PC value. This is used for general non-branching instructions or branch-type instructions."), + value: datapath_state.riscv.state.mem_mux1_to_mem_mux2, + bits: 64, + }, + "memory_data" => LineInformation { + title: String::from("Memory Data"), + description: String::from("The data retrieved from memory, given that the MemRead control signal is set. This may be 32 bits or 64 bits, depending on the RegWidth control signal."), + value: datapath_state.riscv.state.memory_data, + bits: 64, + }, + "new_pc" => LineInformation { + title: String::from("New Program Counter"), + description: String::from("The address of the next instruction to execute. In other words, the next value of the program counter (PC) register."), + value: datapath_state.riscv.state.new_pc, + bits: 64, + }, + "pc" => LineInformation { + title: String::from("Program Counter"), + description: String::from("The address of the currently-executing instruction."), + value: datapath_state.riscv.registers.pc, + bits: 64, + }, + "pc_plus_4" => LineInformation { + title: String::from("PC + 4"), + description: String::from("The address of the currently-executing instruction, plus 4. By default, this will become the next value of the PC register. However, a different address may be used in the case of a branch or jump instruction."), + value: datapath_state.riscv.state.pc_plus_4, + bits: 64, + }, + "pc_plus_4_upper" => LineInformation { + title: String::from("PC + 4 [63-28]"), + description: String::from("The upper 36 bits of PC + 4. This is to be concatenated with the lower 26 bits of the instruction to calculate a jump address."), + value: datapath_state.riscv.state.pc_plus_4 & 0xffff_ffff_f000_0000 >> 28, + bits: 36, + }, + "ra_id" => LineInformation { + title: String::from("Return Address Register Index"), + description: String::from("The value 31. This represents the thirty-second register, the return address register ($ra)."), + value: 31, + bits: 5, + }, + "rd" => LineInformation { + title: String::from("Instruction [11-7] (rd)"), + description: String::from("The rd field. This will be the register written to for an instruction."), + value: datapath_state.riscv.state.rd as u64, + bits: 5, + }, + "read_data_1" => LineInformation { + title: String::from("Read Data 1"), + description: String::from("Data retrieved from the register specified by the rs1 instruction field. Based on the instruction, this may be used as the first input to the ALU, or in the calculation of the next value of the PC register."), + value: datapath_state.riscv.state.read_data_1, + bits: 64, + }, + "read_data_2" => LineInformation { + title: String::from("Read Data 2"), + description: String::from("Data retrieved from the register specified by the rs2 instruction field. Based on the instruction, this may be used as the second input to the ALU or data written to memory."), + value: datapath_state.riscv.state.read_data_2, + bits: 64, + }, + "register_write_data" => LineInformation { + title: String::from("Register Write Data"), + description: String::from("Data that will be written to a general-purpose register, given that RegWrite is set."), + value: datapath_state.riscv.state.register_write_data, + bits: 64, + }, + "relative_pc_branch" => LineInformation { + title: String::from("Branch Address"), + description: String::from("The absolute address used in branch instructions. This is the sign-extended immediate value, shifted left by 2."), + value: datapath_state.riscv.state.relative_pc_branch, + bits: 64, + }, + "rs1" => LineInformation { + title: String::from("Instruction [19-15] (rs1)"), + description: String::from("The rs1 field. Contains the first register to be read for an instruction."), + value: datapath_state.riscv.state.rs1 as u64, + bits: 5, + }, + "rs2" => LineInformation { + title: String::from("Instruction [24-20] (rs2)"), + description: String::from("The rs2 field. Contains the second register to be read for an instruction."), + value: datapath_state.riscv.state.rs2 as u64, + bits: 5, + }, + "shamt" => LineInformation { + title: String::from("Instruction [10-6] (shamt)"), + description: String::from("The shamt (\"shift amount\") field. Specifies the number of bits to shift for those instructions that perform bit-shifting."), + value: datapath_state.riscv.state.shamt as u64, + bits: 5, + }, + "sign_extend" => LineInformation { + title: String::from("Sign-Extended Immediate"), + description: String::from("The immediate field, sign-extended to a 64-bit value."), + value: datapath_state.riscv.state.sign_extend, + bits: 64, + }, + "sign_extend_shift_left_by_2" => LineInformation { + title: String::from("Sign-Extended Immediate << 2"), + description: String::from("The immediate field, sign-extended to a 64-bit value, then shifted left by 2."), + value: datapath_state.riscv.state.sign_extend_shift_left_by_2, + bits: 64, + }, + "write_data" => LineInformation { + title: String::from("Memory Write Data"), + description: String::from("Given that the MemWrite control signal is set, this data will be written to memory."), + value: datapath_state.riscv.state.write_data, + bits: 64, + }, + "write_register" => LineInformation { + title: String::from("Write Register"), + description: String::from("The register that will be written to, assuming RegWrite is set. Depending on the RegDst control signal, this will consist of the rs, rt, or rd register, or 31 (indicating the $ra register)."), + value: datapath_state.riscv.state.write_register_destination as u64, + bits: 5, + }, + "zero_extended_immediate" => LineInformation { + title: String::from("Zero-Extended Immediate"), + description: String::from("The immediate field, zero-extended to a 64-bit value."), + value: datapath_state.riscv.state.imm as u64, + bits: 64, + }, + _ => LineInformation { + title: String::from("[Title]"), + description: String::from("[Description]"), + value: 0, + bits: 0, + }, } - // match variable { - // "alu_input2" => LineInformation { - // title: String::from("ALU Input 2"), - // description: String::from("The second input to the ALU. This is determined by the ALUSrc control signal to select between register data, a sign-extended and left-shifted immediate value, or a zero-extended immediate value."), - // value: datapath_state.riscv.state.alu_input2, - // bits: 64, - // }, - // "alu_result" => LineInformation { - // title: String::from("ALU Result"), - // description: String::from("The result of the calculation performed by the ALU. This is used either as an address to access memory or as a value that is saved into a register."), - // value: datapath_state.riscv.state.alu_result, - // bits: 64, - // }, - // "data_result" => LineInformation { - // title: String::from("Writeback Data"), - // description: String::from("After finishing processing the instruction, this will either be the ALU result, data from memory, or PC + 4, based on the MemToReg control signal. This data is saved into registers."), - // value: datapath_state.riscv.state.data_result, - // bits: 64, - // }, - // "fpu_alu_result" => LineInformation { - // title: String::from("Floating-Point ALU Result"), - // description: String::from("The result of the calculation performed by the floating-point ALU. This is used as an option to be written to a floating-point register, based on the DataWrite and FpuMemToReg control signals."), - // value: datapath_state.riscv.coprocessor_state.alu_result, - // bits: 64, - // }, - // "fpu_branch_decision" => LineInformation { - // title: String::from("FPU Branch Decision"), - // description: String::from("Based on the true/false branch flag, determines whether to branch. (The FpuBranch control signal must also be set.)"), - // value: datapath_state.riscv.coprocessor_state.condition_code_mux as u64, - // bits: 1, - // }, - // "fpu_branch_flag" => LineInformation { - // title: String::from("Instruction [16] (True/False Branch Flag)"), - // description: String::from("The true/false branch flag of branching coprocessor instructions. This flag specifies whether a floating-point branch instruction is BC1T or BC1F."), - // value: datapath_state.riscv.coprocessor_state.branch_flag as u64, - // bits: 1, - // }, - // "fpu_comparator_result" => LineInformation { - // title: String::from("Floating-Point Comparator Result"), - // description: String::from("The result of the comparison of two floating-point values. This is routed to the \"Condition Code\" (cc) register, and will be written there if the CcWrite control signal is set."), - // value: datapath_state.riscv.coprocessor_state.comparator_result, - // bits: 64, - // }, - // "fpu_condition_code" => LineInformation { - // title: String::from("Condition Code Value"), - // description: String::from("Data retrieved from the \"Condition Code\" (cc) register. This specifies whether a previous conditional instruction was true or false."), - // value: datapath_state.riscv.coprocessor_state.condition_code_bit as u64, - // bits: 1, - // }, - // "fpu_condition_code_inverted" => LineInformation { - // title: String::from("Condition Code Value (Inverted)"), - // description: String::from("Inverted form of the condition code register value."), - // value: datapath_state.riscv.coprocessor_state.condition_code_bit_inverted as u64, - // bits: 1, - // }, - // "fpu_data" => LineInformation { - // title: String::from("Floating-Point Data Register Value"), - // description: String::from("Data retrieved from the \"Data\" register. This register acts as a means to communicate data between the main processor and floating-point coprocessor in MTC1 and MFC1 instructions."), - // value: datapath_state.riscv.coprocessor_state.fmt as u64, - // bits: 64, - // }, - // "fpu_data_writeback" => LineInformation { - // title: String::from("Floating-Point Data Writeback"), - // description: String::from("The value from the floating-point unit's \"Data\" register. Depending on the FpuRegWidth control signal, this will be 64-bit data or sign-extended 32-bit data."), - // value: datapath_state.riscv.coprocessor_state.data_writeback, - // bits: 64, - // }, - // "fpu_destination" => LineInformation { - // title: String::from("Floating-Point Write Register"), - // description: String::from("The register that will be written to, assuming FpuRegWrite is set. Depending on the FpuRegDst control signal, this will consist of the fs, ft, or fd register."), - // value: datapath_state.riscv.coprocessor_state.destination as u64, - // bits: 5, - // }, - // "fpu_fd" => LineInformation { - // title: String::from("Instruction [10-6] (fd)"), - // description: String::from("The fd field. Depending on the FpuRegDst control signal, this will be the register written to in a floating-point operation. This register is used as the destination for most floating-point arithmetic instructions."), - // value: datapath_state.riscv.coprocessor_state.fd as u64, - // bits: 5, - // }, - // "fpu_fmt" => LineInformation { - // title: String::from("Instruction [25-21] (fmt)"), - // description: String::from("The fmt field. This is used to distinguish between single-precision and double-precision floating-point instructions."), - // value: datapath_state.riscv.coprocessor_state.fmt as u64, - // bits: 5, - // }, - // "fpu_fp_register_data_from_main_processor" => LineInformation { - // title: String::from("Writeback Data (To Floating-Point Coprocessor)"), - // description: String::from("This data is written to a floating-point register, given FpuMemToReg is set. This line allows data to load from memory to a floating-point register, specifically in the case of the LWC1 instruction."), - // value: datapath_state.riscv.coprocessor_state.fp_register_data_from_main_processor, - // bits: 64, - // }, - // "fpu_fp_register_to_memory" => LineInformation { - // title: String::from("Memory Write Data (from FPU)"), - // description: String::from("If the MemWriteSrc control signal is set, this data will be written to memory. This is used for the SWC1 instruction."), - // value: datapath_state.riscv.coprocessor_state.fp_register_to_memory, - // bits: 64, - // }, - // "fpu_fs" => LineInformation { - // title: String::from("Instruction [15-11] (fs)"), - // description: String::from("The fs field. Contains the first register to be read for a floating-point instruction."), - // value: datapath_state.riscv.coprocessor_state.fs as u64, - // bits: 5, - // }, - // "fpu_ft" => LineInformation { - // title: String::from("Instruction [20-16] (ft)"), - // description: String::from("The ft field. Contains the second register to be read for a floating-point instruction."), - // value: datapath_state.riscv.coprocessor_state.ft as u64, - // bits: 5, - // }, - // "fpu_new_data" => LineInformation { - // title: String::from("New Floating-Point Data Register Value"), - // description: String::from("Data sent to the \"Data\" register. Depending on the DataSrc control signal, this will either be data from the main processor or the floating-point coprocessor. This register acts as a means to communicate data between the main processor and floating-point coprocessor in MTC1 and MFC1 instructions."), - // value: datapath_state.riscv.coprocessor_state.fmt as u64, - // bits: 64, - // }, - // "fpu_read_data_1" => LineInformation { - // title: String::from("FPU Read Data 1"), - // description: String::from("Data retrieved from the register specified by the fs instruction field. This is used as the first inputs to the floating-point ALU and comparator. This can additionally be written to the \"Data\" register, based on the DataSrc and DataWrite control signals."), - // value: datapath_state.riscv.coprocessor_state.read_data_1, - // bits: 64, - // }, - // "fpu_read_data_2" => LineInformation { - // title: String::from("FPU Read Data 2"), - // description: String::from("Data retrieved from the register specified by the ft instruction field. This is used as the second inputs to the floating-point ALU and comparator. This can additionally be used as data to be written to memory, based on the MemWriteSrc control signal."), - // value: datapath_state.riscv.coprocessor_state.read_data_2, - // bits: 64, - // }, - // "fpu_register_write_data" => LineInformation { - // title: String::from("FPU Register Write Data"), - // description: String::from("Data that will be written to a floating-point register, given that FpuRegWrite is set."), - // value: datapath_state.riscv.coprocessor_state.register_write_data, - // bits: 64, - // }, - // "fpu_register_write_mux_to_mux" => LineInformation { - // title: String::from("FPU Register Write Data (When FpuMemToReg is Unset)"), - // description: String::from("Based on the DataWrite control signal, this will either be the result of the floating-point ALU or the contents of the \"Data\" register. (The \"Data\" register is used for transferring data between the processor and floating-point coprocessor.)"), - // value: datapath_state.riscv.coprocessor_state.register_write_mux_to_mux, - // bits: 64, - // }, - // "fpu_sign_extend_data" => LineInformation { - // title: String::from("Floating-Point Data Register Value (Sign-Extended)"), - // description: String::from("In the case where FpuRegWidth indicates a 32-bit width, this is the bottom 32 bits of the value from the \"Data\" register, then sign-extended to 64 bits."), - // value: datapath_state.riscv.coprocessor_state.sign_extend_data, - // bits: 64, - // }, - // "funct" => LineInformation { - // title: String::from("Instruction [5-0] (funct)"), - // description: String::from("The funct field. Contains the type of operation to execute for R-type instructions."), - // value: datapath_state.riscv.state.funct as u64, - // bits: 6, - // }, - // "imm" => LineInformation { - // title: String::from("Instruction [15-0] (immediate)"), - // description: String::from("The immediate field. Contains the 16-bit constant value used for I-type instructions."), - // value: datapath_state.riscv.state.imm as u64, - // bits: 16, - // }, - // "instruction" => LineInformation { - // title: String::from("Instruction"), - // description: String::from("The currently-loaded instruction. This is broken down into different fields, where each field serves a different purpose in identifying what the instruction does."), - // value: datapath_state.riscv.state.instruction as u64, - // bits: 32, - // }, - // "jump_address" => LineInformation { - // title: String::from("Jump Address"), - // description: String::from("The concatenation of the upper 36 bits of PC + 4 with the lower 26 bits of the instruction, shifted left by 2. This is used as the new PC value for J-type instructions."), - // value: datapath_state.riscv.state.jump_address, - // bits: 64, - // }, - // "lower_26" => LineInformation { - // title: String::from("Instruction [25-0]"), - // description: String::from("The lower 26 bits of instruction. This is used as part of the new PC value for J-type instructions."), - // value: datapath_state.riscv.state.lower_26 as u64, - // bits: 26, - // }, - // "lower_26_shifted_left_by_2" => LineInformation { - // title: String::from("Instruction [25-0] << 2"), - // description: String::from("The lower 26 bits of instruction, shifted left by 2. This is used as part of the new PC value for J-type instructions."), - // value: datapath_state.riscv.state.lower_26_shifted_left_by_2 as u64, - // bits: 28, - // }, - // "mem_mux1_to_mem_mux2" => LineInformation { - // title: String::from("Relative PC Address"), - // description: String::from("Based on the control signals for branching and jumping, this address may be the next PC value. This is used for general non-branching instructions or branch-type instructions."), - // value: datapath_state.riscv.state.mem_mux1_to_mem_mux2, - // bits: 64, - // }, - // "memory_data" => LineInformation { - // title: String::from("Memory Data"), - // description: String::from("The data retrieved from memory, given that the MemRead control signal is set. This may be 32 bits or 64 bits, depending on the RegWidth control signal."), - // value: datapath_state.riscv.state.memory_data, - // bits: 64, - // }, - // "new_pc" => LineInformation { - // title: String::from("New Program Counter"), - // description: String::from("The address of the next instruction to execute. In other words, the next value of the program counter (PC) register."), - // value: datapath_state.riscv.state.new_pc, - // bits: 64, - // }, - // "pc" => LineInformation { - // title: String::from("Program Counter"), - // description: String::from("The address of the currently-executing instruction."), - // value: datapath_state.riscv.registers.pc, - // bits: 64, - // }, - // "pc_plus_4" => LineInformation { - // title: String::from("PC + 4"), - // description: String::from("The address of the currently-executing instruction, plus 4. By default, this will become the next value of the PC register. However, a different address may be used in the case of a branch or jump instruction."), - // value: datapath_state.riscv.state.pc_plus_4, - // bits: 64, - // }, - // "pc_plus_4_upper" => LineInformation { - // title: String::from("PC + 4 [63-28]"), - // description: String::from("The upper 36 bits of PC + 4. This is to be concatenated with the lower 26 bits of the instruction to calculate a jump address."), - // value: datapath_state.riscv.state.pc_plus_4 & 0xffff_ffff_f000_0000 >> 28, - // bits: 36, - // }, - // "ra_id" => LineInformation { - // title: String::from("Return Address Register Index"), - // description: String::from("The value 31. This represents the thirty-second register, the return address register ($ra)."), - // value: 31, - // bits: 5, - // }, - // "rd" => LineInformation { - // title: String::from("Instruction [15-11] (rd)"), - // description: String::from("The rd field. Depending on the RegDst control signal, this will be the register written to for an instruction. This register is used as the destination for most R-type instructions."), - // value: datapath_state.riscv.state.rd as u64, - // bits: 5, - // }, - // "read_data_1" => LineInformation { - // title: String::from("Read Data 1"), - // description: String::from("Data retrieved from the register specified by the rs instruction field. Based on the instruction, this may be used as the first input to the ALU, or the next value of the PC register."), - // value: datapath_state.riscv.state.read_data_1, - // bits: 64, - // }, - // "read_data_2" => LineInformation { - // title: String::from("Read Data 2"), - // description: String::from("Data retrieved from the register specified by the rt instruction field. Based on the instruction, this may be used as the second input to the ALU, data written to memory, or data transferred to the floating-point coprocessor."), - // value: datapath_state.riscv.state.read_data_2, - // bits: 64, - // }, - // "register_write_data" => LineInformation { - // title: String::from("Register Write Data"), - // description: String::from("Data that will be written to a general-purpose register, given that RegWrite is set."), - // value: datapath_state.riscv.state.register_write_data, - // bits: 64, - // }, - // "relative_pc_branch" => LineInformation { - // title: String::from("Relative PC Branch Address"), - // description: String::from("The relative address used in branch instructions. This is the sum of PC + 4 and the sign-extended immediate value, shifted left by 2."), - // value: datapath_state.riscv.state.relative_pc_branch, - // bits: 64, - // }, - // "rs" => LineInformation { - // title: String::from("Instruction [25-21] (rs)"), - // description: String::from("The rs field. Contains the first register to be read for an instruction."), - // value: datapath_state.riscv.state.rs as u64, - // bits: 5, - // }, - // "rt" => LineInformation { - // title: String::from("Instruction [20-16] (rt)"), - // description: String::from("The rt field. Contains the second register to be read for an instruction."), - // value: datapath_state.riscv.state.rt as u64, - // bits: 5, - // }, - // "shamt" => LineInformation { - // title: String::from("Instruction [10-6] (shamt)"), - // description: String::from("The shamt (\"shift amount\") field. Specifies the number of bits to shift for those instructions that perform bit-shifting."), - // value: datapath_state.riscv.state.shamt as u64, - // bits: 5, - // }, - // "sign_extend" => LineInformation { - // title: String::from("Sign-Extended Immediate"), - // description: String::from("The immediate field, sign-extended to a 64-bit value."), - // value: datapath_state.riscv.state.sign_extend, - // bits: 64, - // }, - // "sign_extend_shift_left_by_2" => LineInformation { - // title: String::from("Sign-Extended Immediate << 2"), - // description: String::from("The immediate field, sign-extended to a 64-bit value, then shifted left by 2."), - // value: datapath_state.riscv.state.sign_extend_shift_left_by_2, - // bits: 64, - // }, - // "write_data" => LineInformation { - // title: String::from("Memory Write Data"), - // description: String::from("Given that the MemWrite control signal is set, this data will be written to memory."), - // value: datapath_state.riscv.state.write_data, - // bits: 64, - // }, - // "write_register" => LineInformation { - // title: String::from("Write Register"), - // description: String::from("The register that will be written to, assuming RegWrite is set. Depending on the RegDst control signal, this will consist of the rs, rt, or rd register, or 31 (indicating the $ra register)."), - // value: datapath_state.riscv.state.write_register_destination as u64, - // bits: 5, - // }, - // "zero_extended_immediate" => LineInformation { - // title: String::from("Zero-Extended Immediate"), - // description: String::from("The immediate field, zero-extended to a 64-bit value."), - // value: datapath_state.riscv.state.imm as u64, - // bits: 64, - // }, - // _ => LineInformation { - // title: String::from("[Title]"), - // description: String::from("[Description]"), - // value: 0, - // bits: 0, - // }, - // } } } } diff --git a/static/datapath_riscv.svg b/static/datapath_riscv.svg index 02f1d3f2d..a79227d1b 100644 --- a/static/datapath_riscv.svg +++ b/static/datapath_riscv.svg @@ -1,3 +1,3 @@ -
Instruction [31-25] (funct7)
Instruction [31-25] (funct7)
Instruction [14-12] (funct3)
Instruction [14-12] (funct3)
ALUOp
ALUOp
OP2Select
OP2Select
PC
PC
Instruction Memory
Instruction Memory
IMM Decode
IMM Decode
ALU Control
ALU Control
Instruction [31-12] (imm)
Instruction [31-12] (imm)
Add
Add
01S0
Mux
Mux
Branch
Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
WbSel
WbSel
ReadWrite
ReadWrite
Jump Address
Jump Address
Jump
Jump
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [11-7] (rd)
Instruction [11-7] (rd)
Instruction [24-20] (rs2)
Instruction [24-20] (rs2)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
Mux012
Instruction [19-15] (rs1)
Instruction [19-15] (rs1)
IMMSelect
IMMSelect
RegWriteEn
RegWriteEn
Mux0123
Shift Left 2
Shift Left 2
Add
Add
01S0
Mux
Mux
Shift Left 2
Shift Left 2
Branch
Branch
JumpSrc
JumpSrc
OP1Select
OP1Select
Text is not SVG - cannot display
\ No newline at end of file +
Instruction [31-25] (funct7)
Instruction [31-25] (funct7)
Instruction [14-12] (funct3)
Instruction [14-12] (funct3)
ALUOp
ALUOp
OP2Select
OP2Select
PC
PC
Instruction Memory
Instruction Memory
IMM Decode
IMM Decode
ALU Control
ALU Control
Instruction [31-12] (imm)
Instruction [31-12] (imm)
Add
Add
01S0
Mux
Mux
Branch
Branch
PC + 4
PC + 4
Control Unit
Control Unit
Instruction
Instruction
WbSel
WbSel
ReadWrite
ReadWrite
Jump Address
Jump Address
Jump
Jump
Registers
Registers
Read Register 1
Read Register 1
Read Register 2
Read Register 2
Write Register
Write Register
Write Data
Write Data
Read Data 1
Read Data 1
Read Data 2
Read Data 2
Data Memory
Data Memory
Write Data
Write Data
Address
Address
Read Data
Read Data
Instruction [11-7] (rd)
Instruction [11-7] (rd)
Instruction [24-20] (rs2)
Instruction [24-20] (rs2)
Instruction Fetch
Instruction Fetch
Instruction Decode / Register Read
Instruction Decode / Register Read
Execute
Execute
Memory
Memory
Writeback
Writeback
4
4
ALU
ALU
Zero
Zero
01S0
Mux
Mux
01S0
Mux
Mux
Mux012
Instruction [19-15] (rs1)
Instruction [19-15] (rs1)
IMMSelect
IMMSelect
RegWriteEn
RegWriteEn
Mux0123
Shift Left 2
Shift Left 2
Add
Add
01S0
Mux
Mux
Shift Left 2
Shift Left 2
Branch
Branch
JumpSrc
JumpSrc
OP1Select
OP1Select
Text is not SVG - cannot display
\ No newline at end of file From 7428f07f9c47169486030ec88552994992b3ddb7 Mon Sep 17 00:00:00 2001 From: Geetis Date: Fri, 29 Mar 2024 00:21:42 -0400 Subject: [PATCH 32/48] Fixed sign extension --- src/emulation_core/riscv/datapath.rs | 58 +++++++++++++++++++------ src/emulation_core/riscv/instruction.rs | 8 ++-- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 158f57113..11be502bc 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -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 { @@ -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, @@ -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 } @@ -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; @@ -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, @@ -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; } @@ -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, @@ -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), @@ -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. diff --git a/src/emulation_core/riscv/instruction.rs b/src/emulation_core/riscv/instruction.rs index 795949d69..18966cdac 100644 --- a/src/emulation_core/riscv/instruction.rs +++ b/src/emulation_core/riscv/instruction.rs @@ -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, } @@ -149,14 +149,14 @@ impl TryFrom 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, })), From 8d25bf6237101a8b21f4887e1acad4b02424a3f4 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 00:36:43 -0400 Subject: [PATCH 33/48] Address clippy warnings --- src/emulation_core/riscv/datapath.rs | 1 - src/ui/visual_datapath/mod.rs | 1 - src/ui/visual_datapath/utils.rs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 2e8a8523b..1421d1eeb 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -59,7 +59,6 @@ use crate::emulation_core::datapath::{DatapathUpdateSignal, Syscall}; use crate::emulation_core::riscv::registers::RiscGpRegisterType::{X10, X11}; use crate::emulation_core::stack::Stack; use crate::emulation_core::stack::StackFrame; -use gloo_console::log; use serde::{Deserialize, Serialize}; /// An implementation of a datapath for the MIPS64 ISA. diff --git a/src/ui/visual_datapath/mod.rs b/src/ui/visual_datapath/mod.rs index b565fac28..f4abed410 100644 --- a/src/ui/visual_datapath/mod.rs +++ b/src/ui/visual_datapath/mod.rs @@ -25,7 +25,6 @@ pub mod consts; pub mod utils; -use gloo_console::log; use std::{cell::RefCell, rc::Rc}; use gloo_events::EventListener; diff --git a/src/ui/visual_datapath/utils.rs b/src/ui/visual_datapath/utils.rs index 6ed40001a..180a0cd1e 100644 --- a/src/ui/visual_datapath/utils.rs +++ b/src/ui/visual_datapath/utils.rs @@ -541,7 +541,7 @@ pub fn visual_line_to_data( "imm_input" => LineInformation { title: String::from("Instruction [31-12] (immediate)"), description: String::from("The part of the instruction used to extract the imm field from an instruction. In RISC-V, depending on the instruction type, the imm field can be split up within an instruction (S, B, and J type) or even out of order (B and J type)."), - value: 0u64, // FIXME: Use the real line + value: datapath_state.riscv.state.imm_input, bits: 20, }, "instruction" => LineInformation { From bb6b00406ad491d3a68ce158c68078d261e33dc4 Mon Sep 17 00:00:00 2001 From: rharding8 Date: Fri, 29 Mar 2024 00:48:00 -0400 Subject: [PATCH 34/48] Fixed my idiotic programming. Everything works now --- src/emulation_core/riscv/coprocessor.rs | 2 +- src/emulation_core/riscv/instruction.rs | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/emulation_core/riscv/coprocessor.rs b/src/emulation_core/riscv/coprocessor.rs index cc12133d9..9aba1f522 100644 --- a/src/emulation_core/riscv/coprocessor.rs +++ b/src/emulation_core/riscv/coprocessor.rs @@ -480,7 +480,7 @@ impl RiscFpCoprocessor { }; } - /// Set the data line that goes from `Read Data 1` to the multiplexer in the main processor + /// Set the data line that goes from `Read Data 2` to the multiplexer in the main processor /// controlled by [`MemWriteSrc`](super::control_signals::MemWriteSrc). fn write_fp_register_to_memory(&mut self) { self.state.fp_register_to_memory = self.state.read_data_2; diff --git a/src/emulation_core/riscv/instruction.rs b/src/emulation_core/riscv/instruction.rs index 7cad14a46..e1c9bc92f 100644 --- a/src/emulation_core/riscv/instruction.rs +++ b/src/emulation_core/riscv/instruction.rs @@ -121,15 +121,14 @@ impl TryFrom for Instruction { })), // I-type instructions: - OPCODE_IMM | OPCODE_IMM_32 | OPCODE_JALR | OPCODE_LOAD | OPCODE_SYSTEM => { - Ok(Instruction::IType(IType { - imm: (value >> 20) as u16, - rs1: ((value >> 15) & 0x1f) as u8, - funct3: ((value >> 12) & 0x07) as u8, - rd: ((value >> 7) & 0x1f) as u8, - op: (value & 0x7f) as u8, - })) - } + OPCODE_IMM | OPCODE_IMM_32 | OPCODE_JALR | OPCODE_LOAD | OPCODE_SYSTEM + | OPCODE_LOAD_FP => Ok(Instruction::IType(IType { + imm: (value >> 20) as u16, + rs1: ((value >> 15) & 0x1f) as u8, + funct3: ((value >> 12) & 0x07) as u8, + rd: ((value >> 7) & 0x1f) as u8, + op: (value & 0x7f) as u8, + })), // S-type instruction: OPCODE_STORE | OPCODE_STORE_FP => Ok(Instruction::SType(SType { From e35fa7bd26550227dede8077d955717dd17b79f6 Mon Sep 17 00:00:00 2001 From: rharding8 Date: Fri, 29 Mar 2024 01:00:01 -0400 Subject: [PATCH 35/48] Fixed final instructions. --- src/emulation_core/riscv/coprocessor.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/emulation_core/riscv/coprocessor.rs b/src/emulation_core/riscv/coprocessor.rs index 9aba1f522..c20b4ffb4 100644 --- a/src/emulation_core/riscv/coprocessor.rs +++ b/src/emulation_core/riscv/coprocessor.rs @@ -263,6 +263,11 @@ impl RiscFpCoprocessor { _ => self.error("Unsupported Instruction!"), } } + 30 => { + self.signals.data_write = DataWrite::YesWrite; + self.signals.fpu_reg_write = FpuRegWrite::YesWrite; + self.signals.data_src = DataSrc::MainProcessorBits; + } _ => self.error("Unsupported Instruction!"), } From 754bf2dc7f3443933041f490671d655ba9268641 Mon Sep 17 00:00:00 2001 From: Geetis Date: Fri, 29 Mar 2024 01:22:19 -0400 Subject: [PATCH 36/48] Call and tail pseudo-instructions --- src/emulation_core/riscv/datapath.rs | 1 + src/parser/pseudo_instruction_parsing.rs | 174 ++++++++++++++++++++++- 2 files changed, 174 insertions(+), 1 deletion(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 11be502bc..9d432c4ac 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -519,6 +519,7 @@ impl RiscDatapath { // Set the data lines based on the contents of the instruction. // Some lines will hold uninitialized values as a result. + log!("Current Instruction: ", format!("{:?}", self.instruction)); match self.instruction { Instruction::RType(r) => { self.state.rs1 = r.rs1 as u32; diff --git a/src/parser/pseudo_instruction_parsing.rs b/src/parser/pseudo_instruction_parsing.rs index e01c15b70..0a8bc4019 100644 --- a/src/parser/pseudo_instruction_parsing.rs +++ b/src/parser/pseudo_instruction_parsing.rs @@ -1249,7 +1249,7 @@ pub fn expand_pseudo_instructions_and_assign_instruction_numbers_riscv( data: &Vec, monaco_line_info: &mut [MonacoLineInfo], ) { - //figure out list of labels to be used for lw and sw labels + //figure out list of labels let mut list_of_labels: Vec = Vec::new(); for instruction in instructions.clone() { for label in instruction.labels { @@ -1386,6 +1386,178 @@ pub fn expand_pseudo_instructions_and_assign_instruction_numbers_riscv( monaco_line_info[instruction.line_number] .update_pseudo_string(vec![instruction, &mut addi_instruction]); } + "call" => { + let info = PseudoDescription { + name: "call".to_string(), + syntax: "call offset".to_string(), + translation_lines: vec![ + "auipc x6, offset[31:12]".to_string(), + "jalr x1, x6, offset[11:0]".to_string(), + ], + }; + monaco_line_info[instruction.line_number].mouse_hover_string = info.to_string(); + + // Change to function implementation + if !check_operands(instruction, 1) { + continue; + } + + // Parse the immediate value from the second operand + let imm_value: i32 = match instruction.operands[0].token_name.parse() { + Ok(val) => val, + Err(_) => { + instruction.errors.push(Error { + error_name: IncorrectImmediateValue, + token_causing_error: instruction.operands[1].token_name.clone(), + start_end_columns: instruction.operands[1].start_end_columns, + message: "Invalid immediate value".to_string(), + }); + continue; + } + }; + + // Extract the upper and lower parts of the immediate value + let upper_imm = imm_value >> 12; + let lower_imm = imm_value & 0xFFF; + + // auipc instruction + instruction.operator.token_name = "auipc".to_string(); + instruction.operator.start_end_columns = (0, 0); + instruction.operator.token_type = Default::default(); + instruction.operands[0].token_name = "x6".to_string(); + instruction.operands.insert( + 1, + Token { + token_name: upper_imm.to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + ); + instruction.binary = 0; + instruction.errors = vec![]; + instruction.labels = Vec::new(); + + // jalr instruction + let mut jalr_instruction = Instruction { + operator: Token { + token_name: "jalr".to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + operands: vec![ + Token { + token_name: "x1".to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + Token { + token_name: "x6".to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + Token { + token_name: lower_imm.to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + ], + binary: 0, + instruction_number: instruction.instruction_number + 1, + line_number: instruction.line_number, + errors: vec![], + labels: Vec::new(), + }; + vec_of_added_instructions.push(jalr_instruction.clone()); + + monaco_line_info[instruction.line_number] + .update_pseudo_string(vec![instruction, &mut jalr_instruction]); + } + "tail" => { + let info = PseudoDescription { + name: "tail".to_string(), + syntax: "tail offset".to_string(), + translation_lines: vec![ + "auipc x6, offset[31:12]".to_string(), + "jalr x0, x6, offset[11:0]".to_string(), + ], + }; + monaco_line_info[instruction.line_number].mouse_hover_string = info.to_string(); + + // Change to function implementation + if !check_operands(instruction, 1) { + continue; + } + + // Parse the immediate value from the second operand + let imm_value: i32 = match instruction.operands[0].token_name.parse() { + Ok(val) => val, + Err(_) => { + instruction.errors.push(Error { + error_name: IncorrectImmediateValue, + token_causing_error: instruction.operands[1].token_name.clone(), + start_end_columns: instruction.operands[1].start_end_columns, + message: "Invalid immediate value".to_string(), + }); + continue; + } + }; + + // Extract the upper and lower parts of the immediate value + let upper_imm = imm_value >> 12; + let lower_imm = imm_value & 0xFFF; + + // auipc instruction + instruction.operator.token_name = "auipc".to_string(); + instruction.operator.start_end_columns = (0, 0); + instruction.operator.token_type = Default::default(); + instruction.operands[0].token_name = "x6".to_string(); + instruction.operands.insert( + 1, + Token { + token_name: upper_imm.to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + ); + instruction.binary = 0; + instruction.errors = vec![]; + instruction.labels = Vec::new(); + + // jalr instruction + let mut jalr_instruction = Instruction { + operator: Token { + token_name: "jalr".to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + operands: vec![ + Token { + token_name: "x0".to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + Token { + token_name: "x6".to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + Token { + token_name: lower_imm.to_string(), + start_end_columns: (0, 0), + token_type: Default::default(), + }, + ], + binary: 0, + instruction_number: instruction.instruction_number + 1, + line_number: instruction.line_number, + errors: vec![], + labels: Vec::new(), + }; + vec_of_added_instructions.push(jalr_instruction.clone()); + + monaco_line_info[instruction.line_number] + .update_pseudo_string(vec![instruction, &mut jalr_instruction]); + } "mv" => { // Set Pseudo Description let info = PseudoDescription { From ecf76fdd73bfc0ded7b0ef3aeca0ecbdf4a79215 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 01:28:05 -0400 Subject: [PATCH 37/48] Connect the FP registers to the visual display --- src/agent.rs | 5 +++++ src/agent/datapath_reducer.rs | 18 +++++++++++++++++- src/agent/messages.rs | 3 ++- src/bin/main.rs | 3 +-- src/emulation_core/riscv/coprocessor.rs | 4 ++-- src/emulation_core/riscv/registers.rs | 23 +++++++++++------------ src/ui/regview/component.rs | 4 ++-- 7 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/agent.rs b/src/agent.rs index 1b50b1d01..16d19bb9c 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -159,6 +159,11 @@ pub async fn emulation_core_agent(scope: ReactorScope) state.updates.changed_stack, RiscStateUpdate::UpdateStack(datapath.stack.clone()) ); + send_update_riscv!( + state.scope, + state.updates.changed_coprocessor_registers, + RiscStateUpdate::UpdateCoprocessorRegisters(datapath.coprocessor.registers) + ); } } state.updates = Default::default(); diff --git a/src/agent/datapath_reducer.rs b/src/agent/datapath_reducer.rs index 2e32746e9..6c6160515 100644 --- a/src/agent/datapath_reducer.rs +++ b/src/agent/datapath_reducer.rs @@ -8,7 +8,9 @@ use crate::emulation_core::mips::gp_registers::{GpRegisterType, GpRegisters}; use crate::emulation_core::mips::memory::Memory; use crate::emulation_core::register::{RegisterType, Registers}; use crate::emulation_core::riscv::datapath::{RiscDatapathState, RiscStage}; -use crate::emulation_core::riscv::registers::{RiscGpRegisterType, RiscGpRegisters}; +use crate::emulation_core::riscv::registers::{ + RiscFpRegisters, RiscGpRegisterType, RiscGpRegisters, +}; use crate::emulation_core::stack::Stack; use gloo_console::log; use std::rc::Rc; @@ -40,6 +42,7 @@ pub struct MipsCoreState { pub struct RiscCoreState { pub state: RiscDatapathState, pub registers: RiscGpRegisters, + pub coprocessor_registers: RiscFpRegisters, pub memory: Memory, pub current_stage: RiscStage, pub stack: Stack, @@ -151,6 +154,12 @@ impl Reducible for DatapathReducer { stack, ..self.riscv.clone() }, + RiscStateUpdate::UpdateCoprocessorRegisters(coprocessor_registers) => { + RiscCoreState { + coprocessor_registers, + ..self.riscv.clone() + } + } }, ..(*self).clone() }, @@ -180,6 +189,13 @@ impl DatapathReducer { } } + pub fn get_dyn_fp_registers(&self) -> Vec<(Rc, u64)> { + match self.current_architecture { + MIPS => self.mips.coprocessor_registers.get_dyn_register_list(), + RISCV => self.riscv.coprocessor_registers.get_dyn_register_list(), + } + } + pub fn get_memory(&self) -> &Memory { match self.current_architecture { MIPS => &self.mips.memory, diff --git a/src/agent/messages.rs b/src/agent/messages.rs index 2943f4caa..51a8dbbfd 100644 --- a/src/agent/messages.rs +++ b/src/agent/messages.rs @@ -4,7 +4,7 @@ use crate::emulation_core::mips::fp_registers::FpRegisters; use crate::emulation_core::mips::gp_registers::GpRegisters; use crate::emulation_core::mips::memory::Memory; use crate::emulation_core::riscv::datapath::{RiscDatapathState, RiscStage}; -use crate::emulation_core::riscv::registers::RiscGpRegisters; +use crate::emulation_core::riscv::registers::{RiscFpRegisters, RiscGpRegisters}; use crate::emulation_core::stack::Stack; use crate::emulation_core::{architectures::AvailableDatapaths, mips::datapath::Stage}; use serde::{Deserialize, Serialize}; @@ -44,6 +44,7 @@ pub enum MipsStateUpdate { pub enum RiscStateUpdate { UpdateState(RiscDatapathState), UpdateRegisters(RiscGpRegisters), + UpdateCoprocessorRegisters(RiscFpRegisters), UpdateMemory(Memory), UpdateStage(RiscStage), UpdateStack(Stack), diff --git a/src/bin/main.rs b/src/bin/main.rs index e6f7d9c82..3f9a84992 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -32,7 +32,6 @@ use web_sys::HtmlInputElement; use yew::prelude::*; use yew::{html, Html, Properties}; -use swim::emulation_core::register::Registers; use swim::emulation_core::riscv::datapath::RiscStage; use yew_agent::Spawnable; @@ -657,7 +656,7 @@ fn app(props: &AppProps) -> Html { // Right column - + } diff --git a/src/emulation_core/riscv/coprocessor.rs b/src/emulation_core/riscv/coprocessor.rs index c20b4ffb4..c23ef4041 100644 --- a/src/emulation_core/riscv/coprocessor.rs +++ b/src/emulation_core/riscv/coprocessor.rs @@ -4,7 +4,7 @@ use std::ops::Neg; use super::constants::*; use super::instruction::Instruction; -use super::registers::FpRegisters; +use super::registers::RiscFpRegisters; use super::{constants::RISC_NAN, control_signals::floating_point::*}; use serde::{Deserialize, Serialize}; @@ -18,7 +18,7 @@ pub struct RiscFpCoprocessor { pub signals: FpuControlSignals, pub state: RiscFpuState, pub is_halted: bool, - pub registers: FpRegisters, + pub registers: RiscFpRegisters, pub condition_code: u64, pub data: u64, } diff --git a/src/emulation_core/riscv/registers.rs b/src/emulation_core/riscv/registers.rs index c5d763b8e..aeb28bcc7 100644 --- a/src/emulation_core/riscv/registers.rs +++ b/src/emulation_core/riscv/registers.rs @@ -260,12 +260,12 @@ impl IntoIterator for RiscGpRegisters { /// Collection of general-purpose registers used by the datapath. #[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)] -pub struct FpRegisters { +pub struct RiscFpRegisters { pub fpr: [u64; 32], } /// Specifies all of the valid registers accessible in an instance -/// of [`FpRegisters`]. +/// of [`RiscFpRegisters`]. #[derive(Clone, Copy, Debug, Display, EnumIter, EnumString, Eq, PartialEq)] #[strum(ascii_case_insensitive)] #[strum(serialize_all = "lowercase")] @@ -302,7 +302,6 @@ pub enum FpRegisterType { F29 = 29, F30 = 30, F31 = 31, - FCSR = 32, } impl RegisterType for FpRegisterType { @@ -314,7 +313,7 @@ impl RegisterType for FpRegisterType { } } -impl Registers for FpRegisters { +impl Registers for RiscFpRegisters { fn get_dyn_register_list(&self) -> Vec<(Rc, u64)> { self.into_iter() .map(|(register, val)| { @@ -325,7 +324,7 @@ impl Registers for FpRegisters { } } -impl ToString for FpRegisters { +impl ToString for RiscFpRegisters { fn to_string(&self) -> String { let mut output = String::new(); @@ -342,7 +341,7 @@ impl ToString for FpRegisters { } } -impl Index<&str> for FpRegisters { +impl Index<&str> for RiscFpRegisters { type Output = u64; // Convert string to the corresponding RegistersEnum value and use this to index. @@ -355,7 +354,7 @@ impl Index<&str> for FpRegisters { } } -impl IndexMut<&str> for FpRegisters { +impl IndexMut<&str> for RiscFpRegisters { // Convert string to the corresponding RegistersEnum value and use this to index. // If this is an invalid string, no enum will be returned, causing a panic as desired. fn index_mut(&mut self, index: &str) -> &mut Self::Output { @@ -366,7 +365,7 @@ impl IndexMut<&str> for FpRegisters { } } -impl Index for FpRegisters { +impl Index for RiscFpRegisters { type Output = u64; fn index(&self, index: FpRegisterType) -> &Self::Output { @@ -374,7 +373,7 @@ impl Index for FpRegisters { } } -impl IndexMut for FpRegisters { +impl IndexMut for RiscFpRegisters { fn index_mut(&mut self, index: FpRegisterType) -> &mut Self::Output { &mut self.fpr[index as usize] } @@ -388,7 +387,7 @@ impl IndexMut for FpRegisters { /// normally just "add 1" to get to the next register, we use an internal iterator /// that can track the progression of one [`FpRegisterType`] to the next. pub struct FpRegistersIter { - registers: FpRegisters, + registers: RiscFpRegisters, register_iter: FpRegisterTypeIter, } @@ -408,11 +407,11 @@ impl Iterator for FpRegistersIter { /// [`IntoIterator`] is a standard library trait that can convert any type into /// an [`Iterator`]. In this case, this is an instance of [`FpRegistersIter`] with all the /// data in the registers and a new [`FpRegisterTypeIter`]. -impl IntoIterator for FpRegisters { +impl IntoIterator for RiscFpRegisters { type Item = (FpRegisterType, u64); type IntoIter = FpRegistersIter; - /// Consumes the [`FpRegisters`] struct to create a new [`FpRegistersIter`] that can + /// Consumes the [`RiscFpRegisters`] struct to create a new [`FpRegistersIter`] that can /// be iterated over. fn into_iter(self) -> Self::IntoIter { FpRegistersIter { diff --git a/src/ui/regview/component.rs b/src/ui/regview/component.rs index eb4abcf14..f7953e28c 100644 --- a/src/ui/regview/component.rs +++ b/src/ui/regview/component.rs @@ -177,8 +177,8 @@ pub fn generate_fpr_rows(props: &Regviewprops, unit_type: UnitState) -> Html { }} value={ match unit_type { - UnitState::Float => format!("{:e}", data).to_string(), - UnitState::Double => format!("{:e}", data).to_string(), + UnitState::Float => format!("{}", f32::from_bits(data as u32)).to_string(), + UnitState::Double => format!("{}", f64::from_bits(data)).to_string(), UnitState::Hex => format!("{:#04x?}", data).to_string(), UnitState::Bin => format!("{:#b}", data).to_string(), _ => format!("{:?}", data).to_string(), From 953a311e69261a408d41e8f542d161ba10890304 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 01:50:09 -0400 Subject: [PATCH 38/48] Avoid highlighting the first line at the end of execution --- src/bin/main.rs | 11 ++++++++--- src/ui/swim_editor/component.rs | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index c54f2598e..94a8bc115 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -235,7 +235,10 @@ fn app(props: &AppProps) -> Html { let list_of_line_numbers = program_info.address_to_line_number; let index = datapath_state.get_pc() as usize / 4; - editor_curr_line.set(*list_of_line_numbers.get(index).unwrap_or(&0) as f64 + 1.0); // add one to account for the editor's line numbers + editor_curr_line.set(match list_of_line_numbers.get(index) { + Some(val) => (val + 1) as f64, + None => 0f64, + }); memory_curr_instr.set(datapath_state.get_pc()); // Execute instruction @@ -294,8 +297,10 @@ fn app(props: &AppProps) -> Html { let list_of_line_numbers = program_info.address_to_line_number; let index = datapath_state.get_pc() as usize / 4; - editor_curr_line - .set(*list_of_line_numbers.get(index).unwrap_or(&0) as f64 + 1.0); + editor_curr_line.set(match list_of_line_numbers.get(index) { + Some(val) => (val + 1) as f64, + None => 0f64, + }); memory_curr_instr.set(datapath_state.get_pc()); communicator.execute_stage(); } else { diff --git a/src/ui/swim_editor/component.rs b/src/ui/swim_editor/component.rs index b6d41bd6a..0300cedeb 100644 --- a/src/ui/swim_editor/component.rs +++ b/src/ui/swim_editor/component.rs @@ -118,7 +118,10 @@ pub fn SwimEditor(props: &SwimEditorProps) -> Html { let program_info = props.program_info.clone(); let list_of_line_numbers = program_info.address_to_line_number; let index = props.pc as usize / 4; - curr_line.set(*list_of_line_numbers.get(index).unwrap_or(&0) as f64 + 1.0); + curr_line.set(match list_of_line_numbers.get(index) { + Some(val) => (val + 1) as f64, + None => 0f64, + }); // add one to account for the editor's line numbers } From af5afa84992e17bc4da965911d00dca055d4fb09 Mon Sep 17 00:00:00 2001 From: Geetis Date: Fri, 29 Mar 2024 01:57:49 -0400 Subject: [PATCH 39/48] Sign-extend S-type and adjust riscv_fib --- src/emulation_core/riscv/datapath.rs | 10 +++++++++- static/assembly_examples/riscv_fib.asm | 3 --- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 9d432c4ac..cac824a8d 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -582,7 +582,15 @@ impl RiscDatapath { } 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, + ImmSelect::SType => { + let uimm = ((signed_imm << 7) | self.state.imm1) << 5 | self.state.imm2; + let mask = 0b100000000000; + if uimm & mask != 0 { + !(!uimm & 0xFFF) + } else { + self.state.imm + } + } ImmSelect::BType => self.state.imm, ImmSelect::UType => ((signed_imm << 20) | self.state.imm) << 12, ImmSelect::JType => self.state.imm, diff --git a/static/assembly_examples/riscv_fib.asm b/static/assembly_examples/riscv_fib.asm index 424c2c231..51fd1f6d4 100644 --- a/static/assembly_examples/riscv_fib.asm +++ b/static/assembly_examples/riscv_fib.asm @@ -15,13 +15,11 @@ L2: lw a5,-20(s0) addi a5,a5,-1 mv a0,a5 - auipc ra,0 jalr ra # 26 <.L2+0x8> mv s1,a0 lw a5,-20(s0) addi a5,a5,-2 mv a0,a5 - auipc ra,0 jalr ra # 38 <.L2+0x1a> mv a5,a0 add a5,a5,s1 @@ -42,7 +40,6 @@ main: li a5,5 sw a5,-20(s0) lw a0,-20(s0) - auipc ra,0 jalr ra # 62 sw a0,-24(s0) lw a5,-24(s0) From 0d1076dcd25b8657bcbbc697397c890961848958 Mon Sep 17 00:00:00 2001 From: rharding8 Date: Fri, 29 Mar 2024 02:08:15 -0400 Subject: [PATCH 40/48] Fixed my stupid coprocessor. --- src/emulation_core/riscv/coprocessor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emulation_core/riscv/coprocessor.rs b/src/emulation_core/riscv/coprocessor.rs index c23ef4041..a542144e8 100644 --- a/src/emulation_core/riscv/coprocessor.rs +++ b/src/emulation_core/riscv/coprocessor.rs @@ -321,7 +321,7 @@ impl RiscFpCoprocessor { } }; } - _ => self.error("Unsupported Instruction!"), + _ => (), } } From 9a442de7299b78a0cfda397fb2c684f7c81f9075 Mon Sep 17 00:00:00 2001 From: Geetis Date: Fri, 29 Mar 2024 02:52:11 -0400 Subject: [PATCH 41/48] Fixed S-type instruction immediate --- src/emulation_core/riscv/datapath.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 7aceedf24..516a8a4e6 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -623,7 +623,7 @@ impl RiscDatapath { if uimm & mask != 0 { !(!uimm & 0xFFF) } else { - self.state.imm + uimm } } ImmSelect::BType => self.state.imm, From 4da8faa9b781439d82c5dcf0e8ca36c74b490d2a Mon Sep 17 00:00:00 2001 From: Geetis Date: Fri, 29 Mar 2024 03:11:31 -0400 Subject: [PATCH 42/48] Updated RISC-V fib. THANKS BROOKS!!!!! <3 --- static/assembly_examples/riscv_fib.asm | 72 +++++++++----------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/static/assembly_examples/riscv_fib.asm b/static/assembly_examples/riscv_fib.asm index 51fd1f6d4..e5d745b27 100644 --- a/static/assembly_examples/riscv_fib.asm +++ b/static/assembly_examples/riscv_fib.asm @@ -1,50 +1,28 @@ -fib: - addi sp,sp,-32 - sw ra,28(sp) - sw s0,24(sp) - sw s1,20(sp) - addi s0,sp,32 - sw a0,-20(s0) - lw a4,-20(s0) - li a5,1 - blt a5,a4,L2 - lw a5,-20(s0) - j L3 +fib(int): + # t0 and t1 are the last two values of the fib sequence + ori t0, zero, 0 # a_n-2 + ori t1, zero, 1 # a_n-1 + ori t2, zero, 1 # a_n + ori t3, zero, 1 # index -L2: - lw a5,-20(s0) - addi a5,a5,-1 - mv a0,a5 - jalr ra # 26 <.L2+0x8> - mv s1,a0 - lw a5,-20(s0) - addi a5,a5,-2 - mv a0,a5 - jalr ra # 38 <.L2+0x1a> - mv a5,a0 - add a5,a5,s1 - -L3: - mv a0,a5 - lw ra,28(sp) - lw s0,24(sp) - lw s1,20(sp) - addi sp,sp,32 - ret +COND: + bne a0, t3, LOOP # If we've reached our index, return + or a1, zero, t2 + #Pseudo-Instruction: ret + jalr x0, x1, 0 #Pseudo-Instruction Translation +LOOP: + # Legendary fibonacci calculation + add t2, t0, t1 + or t0, zero, t1 + or t1, zero, t2 + addi t3, t3, 1 + jal x0, COND + main: - addi sp,sp,-32 - sw ra,28(sp) - sw s0,24(sp) - addi s0,sp,32 - li a5,5 - sw a5,-20(s0) - lw a0,-20(s0) - jalr ra # 62 - sw a0,-24(s0) - lw a5,-24(s0) - mv a0,a5 - lw ra,28(sp) - lw s0,24(sp) - addi sp,sp,32 - ret \ No newline at end of file + ori a0, zero, 15 + jal ra, fib(int) + ori a0, zero, 1 + ecall + ori a0, zero, 0 + ecall \ No newline at end of file From 9e531a8b08ef7145cc72cda2680aaa39b5ea467b Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 04:06:09 -0400 Subject: [PATCH 43/48] Add new data lines for visual datapath --- src/emulation_core/riscv/datapath.rs | 9 ++++----- src/ui/visual_datapath/utils.rs | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 3a126930f..906b09a6e 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -178,6 +178,7 @@ pub struct RiscDatapathState { pub write_data: u64, pub imm_input: u64, + pub i_type_jump: u64, } /// The possible stages the datapath could be in during execution. @@ -393,7 +394,7 @@ impl RiscDatapath { self.set_control_signals(); self.set_immediate(); self.read_registers(); - + self.construct_jump_address(); self.coprocessor.stage_instruction_decode(); self.coprocessor .set_data_from_main_processor(self.state.read_data_1); @@ -1065,10 +1066,6 @@ impl RiscDatapath { self.state.alu_result = self.state.alu_result as u32 as i64 as u64; } - if self.signals.branch_jump == BranchJump::J { - self.construct_jump_address(); - } - // Set the zero bit/signal. self.datapath_signals.alu_z = match self.state.alu_result { 0 => AluZ::YesZero, @@ -1104,6 +1101,8 @@ impl RiscDatapath { } fn construct_jump_address(&mut self) { + self.state.i_type_jump = + (self.state.imm as u64 + self.state.read_data_1) & 0xfffffffffffffff0; self.state.jump_address = match self.instruction { Instruction::IType(_i) => self.state.imm as u64 + self.state.read_data_1, Instruction::JType(_j) => self.state.imm as u64 * 4, diff --git a/src/ui/visual_datapath/utils.rs b/src/ui/visual_datapath/utils.rs index 180a0cd1e..639d431eb 100644 --- a/src/ui/visual_datapath/utils.rs +++ b/src/ui/visual_datapath/utils.rs @@ -544,18 +544,24 @@ pub fn visual_line_to_data( value: datapath_state.riscv.state.imm_input, bits: 20, }, + "imm_shifted_left_by_2" => LineInformation { + title: String::from("Immediate (shifted left by 2)"), + description: String::from("The immediate field shifed left by two bits. This value is later used as a jump address."), + value: (datapath_state.riscv.state.imm << 2) as u64, + bits: 22, + }, + "i_type_address" => LineInformation { + title: String::from("I Type Jump Address"), + description: String::from("The jump address used for I type jump instructions. This is calculated by adding the immediate value and the contents of rs1."), + value: datapath_state.riscv.state.i_type_jump, + bits: 22, + }, "instruction" => LineInformation { title: String::from("Instruction"), description: String::from("The currently-loaded instruction. This is broken down into different fields, where each field serves a different purpose in identifying what the instruction does."), value: datapath_state.riscv.state.instruction as u64, bits: 32, }, - "i_type_address" => LineInformation { - title: String::from("I type jump address"), - description: String::from("The jump address used for I type instructions. Calculated from the data in rs1 and imm."), - value: 0u64, // FIXME: Use the real line - bits: 16, - }, "jump_address" => LineInformation { title: String::from("Jump Address"), description: String::from("The calculated next program counter for jump instructions. For I type instructions, this is the immediate value added to the data in rs1. For U type instructions, this is the immediate value shifted left by 2."), From 8204869e764bab6208749af4e8bd6f2b8667b60a Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 05:04:19 -0400 Subject: [PATCH 44/48] Fix negative imm values --- src/emulation_core/riscv/datapath.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index b20b354e8..41a3f0acb 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -1102,10 +1102,10 @@ impl RiscDatapath { fn construct_jump_address(&mut self) { self.state.i_type_jump = - (self.state.imm as u64 + self.state.read_data_1) & 0xfffffffffffffff0; + ((self.state.imm as u64).wrapping_add(self.state.read_data_1)) & 0xfffffffffffffff0; self.state.jump_address = match self.instruction { - Instruction::IType(_i) => self.state.imm as u64 + self.state.read_data_1, - Instruction::JType(_j) => self.state.imm as u64 * 4, + Instruction::IType(_i) => (self.state.imm as u64).wrapping_add(self.state.read_data_1), + Instruction::JType(_j) => (self.state.imm as u64).wrapping_shl(2), _ => self.state.jump_address, } } From 259873f203cb6c658a2b9282fbe34c315d586fbc Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 05:09:01 -0400 Subject: [PATCH 45/48] Fix breakpoints regression --- src/agent.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agent.rs b/src/agent.rs index 16d19bb9c..833913b52 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -309,7 +309,7 @@ impl EmulatorCoreAgentState { DatapathRef::MIPS(datapath) => datapath.registers.pc, DatapathRef::RISCV(datapath) => datapath.registers.pc, }; - if self.breakpoints.contains(¤t_pc) && self.updates.hit_breakpoint { + if self.breakpoints.contains(¤t_pc) || self.updates.hit_breakpoint { self.executing = false; // Unset the hit_breakpoint flag after processing self.updates.hit_breakpoint = false; From 2a6a3d7494803edd8cfd0f64e1529041b8db65c4 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 05:27:49 -0400 Subject: [PATCH 46/48] Evil hack to fix the stack view in RISC-V --- src/emulation_core/riscv/datapath.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/emulation_core/riscv/datapath.rs b/src/emulation_core/riscv/datapath.rs index 41a3f0acb..19159bc9a 100644 --- a/src/emulation_core/riscv/datapath.rs +++ b/src/emulation_core/riscv/datapath.rs @@ -473,7 +473,9 @@ impl RiscDatapath { changed_stack = true; } - let hit_jump = matches!(self.signals.branch_jump, BranchJump::J); + let hit_jump = matches!(self.signals.branch_jump, BranchJump::J) + // Evil hack to stop JALR from appearing in the stack frame viewer + && ((self.state.instruction & 0b1111111) as u8 != OPCODE_JALR); if hit_jump { // Add current line to stack if we call a function let frame = StackFrame::new( From f5863aca17456663debfb7f25494df389eba84f6 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 05:30:47 -0400 Subject: [PATCH 47/48] OOPs silly me I used the wrong register for sp and that broke the stack frame --- src/agent/datapath_reducer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agent/datapath_reducer.rs b/src/agent/datapath_reducer.rs index b651e1023..cb09a691a 100644 --- a/src/agent/datapath_reducer.rs +++ b/src/agent/datapath_reducer.rs @@ -178,7 +178,7 @@ impl DatapathReducer { pub fn get_sp(&self) -> u64 { match self.current_architecture { MIPS => self.mips.registers[GpRegisterType::Sp], - RISCV => self.riscv.registers[RiscGpRegisterType::X1], + RISCV => self.riscv.registers[RiscGpRegisterType::X2], } } From 3514992a20d52b3b4bd140666b1cf1e2d6cee530 Mon Sep 17 00:00:00 2001 From: Brooks McKinley <31021010+brooksmckinley@users.noreply.github.com> Date: Fri, 29 Mar 2024 05:33:53 -0400 Subject: [PATCH 48/48] Recursive version of riscv_fib to show off the stack viewer --- .../assembly_examples/riscv_fib_recursive.asm | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 static/assembly_examples/riscv_fib_recursive.asm diff --git a/static/assembly_examples/riscv_fib_recursive.asm b/static/assembly_examples/riscv_fib_recursive.asm new file mode 100644 index 000000000..5d67e4bfd --- /dev/null +++ b/static/assembly_examples/riscv_fib_recursive.asm @@ -0,0 +1,55 @@ +fib(int): + # Stack variables: | return addr | argument | n - 1 | n - 2 | + + # Save return address and argument + sw ra, 0(sp) + sw a0, 4(sp) + + ori t0, zero, 0 + ori t1, zero, 1 + beq a0, t0, RET_0 + beq a0, t1, RET_1 + + # Recursive call for fib(n-1) + addi a0, a0, -1 # Setting arg + addi sp, sp, -16 # Making space on the stack + jal ra, fib(int) + sw a1, 8(sp) # Storing the return value + lw a0, 4(sp) # Restoring our original argument + + # Recursive call for fib(n-2) + addi a0, a0, -2 + addi sp, sp, -16 + jal ra, fib(int) + sw a1, 12(sp) + + # Adding together n-1 and n-2 and returning + lw t0, 8(sp) + lw t1, 12(sp) + + add a1, t0, t1 + lw ra, 0(sp) + addi sp, sp, 16 + #Pseudo-Instruction: ret + jalr x0, x1, 0 #Pseudo-Instruction Translation + + +RET_0: + ori a1, zero, 0 + addi sp, sp, 16 + #Pseudo-Instruction: ret + jalr x0, x1, 0 #Pseudo-Instruction Translation +RET_1: + ori a1, zero, 1 + addi sp, sp, 16 + #Pseudo-Instruction: ret + jalr x0, x1, 0 #Pseudo-Instruction Translation + +main: + ori a0, zero, 5 + addi sp, sp, -16 + jal ra, fib(int) + ori a0, zero, 1 + ecall + ori a0, zero, 0 + ecall