- Set rd to 1 if the value in
- rs1 is less than the value in
- rs2, otherwise 0 (both values are
- treated as signed)
-
-
-
-
- SLTU rd, rs1, rs2
-
-
- rd = rs1 <u rs2
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- rs2, otherwise 0 (both values are
- treated as unsigned)
-
-
-
-
- AND rd, rs1, rs2
-
-
- rd = rs1 & rs2
-
-
-
-
-
- OR rd, rs1, rs2
-
-
- rd = rs1 | rs2
-
-
-
-
-
- XOR rd, rs1, rs2
-
-
- rd = rs1 ^ rs2
-
-
-
-
-
- MUL rd, rs1, rs2
-
-
- rd = rs1 * rs2
-
-
- (M), places the lower 32 bits of the result in the
- destination register
-
-
-
-
- MULH rd, rs1, rs2
-
-
- rd = rs1 s*s rs2
-
-
- (M), places the upper 32 bits of the result in the
- destination register, both rs1 and rs2 are treated
- as signed
-
-
-
-
- MULHU rd, rs1, rs2
-
-
- rd = rs1 u*u rs2
-
-
- (M), places the upper 32 bits of the result in the
- destination register, both rs1 and rs2 are treated
- as unsigned
-
-
-
-
- MULHSU rd, rs1, rs2
-
-
- rd = rs1 s*u rs2
-
-
- (M), places the upper 32 bits of the result in the
- destination register, rs1 treated as signed, rs2
- treated as unsigned
-
-
-
-
- DIV rd, rs1, rs2
-
-
- rd = rs1 /s rs2
-
-
(M), signed integer division
-
-
-
- DIVU rd, rs1, rs2
-
-
- rd = rs1 /u rs2
-
-
(M), unsigned integer division
-
-
-
- REM rd, rs1, rs2
-
-
- rd = rs1 %s rs2
-
-
(M), remainder of signed integer division
-
-
-
- REMU rd, rs1, rs2
-
-
- rd = rs1 %u rs2
-
-
(M), remainder of unsigned integer division
-
-
-
-
-
- Note: Instructions marked with (M) are part of the "M” Standard
- Extension for Integer Multiplication and Division.
-
-
-
I-Type
-
- Unless otherwise specified, the immediate (imm) has a
- length of 12 bits and is sign extended to 32 bits.
-
- var is a variable name, index is an
- optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADDI rd, rs1, imm
-
-
- rd = rs1 + imm
-
-
-
-
-
- SLTI rd, rs1, imm
-
-
- rd = rs1 <s imm
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- imm, otherwise 0 (both values are
- treated as signed)
-
-
-
-
- SLTIU rd, rs1, imm
-
-
- rd = rs1 <u imm
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- imm, otherwise 0 (both values are
- treated as unsigned)
-
-
-
-
- ANDI rd, rs1, imm
-
-
- rd = rs1 & imm
-
-
-
-
-
- ORI rd, rs1, imm
-
-
- rd = rs1 | imm
-
-
-
-
-
- XORI rd, rs1, imm
-
-
- rd = rs1 ^ imm
-
-
-
-
-
- SLLI rd, rs1, imm
-
-
- rd = rs1 << imm
-
-
- imm is unsigned, with a length of 5
- bits
-
-
-
-
- SRLI rd, rs1, imm
-
-
- rd = rs1 >> imm
-
-
- Logical right shift. imm
- is unsigned, with a length of 5 bits
-
-
-
-
- SRAI rd, rs1, imm
-
-
- rd = rs1 >>a imm
-
-
- Arithmetic right shift. imm
- is unsigned, with a length of 5 bits
-
- Jump and link register.
- rd is set to the address of the
- instruction following the jump. The jump target is
- rs1 + imm
- with the least significant bit cleared.
-
+ Set rd to 1 if the
+ value in rs1 is less
+ than the value in rs2,
+ otherwise 0 (both values are treated
+ as signed)
+
+
+
+
+ SLTU rd, rs1, rs2
+
+
+ rd = rs1 <u rs2
+
+
+ Set rd to 1 if the
+ value in rs1 is less
+ than the value in rs2,
+ otherwise 0 (both values are treated
+ as unsigned)
+
+
+
+
+ AND rd, rs1, rs2
+
+
+ rd = rs1 & rs2
+
+
+
+
+
+ OR rd, rs1, rs2
+
+
+ rd = rs1 | rs2
+
+
+
+
+
+ XOR rd, rs1, rs2
+
+
+ rd = rs1 ^ rs2
+
+
+
+
+
+ MUL rd, rs1, rs2
+
+
+ rd = rs1 * rs2
+
+
+ (M), places the lower 32 bits of the
+ result in the destination register
+
+
+
+
+ MULH rd, rs1, rs2
+
+
+ rd = rs1 s*s rs2
+
+
+ (M), places the upper 32 bits of the
+ result in the destination register,
+ both rs1 and rs2 are treated as
+ signed
+
+
+
+
+ MULHU rd, rs1, rs2
+
+
+ rd = rs1 u*u rs2
+
+
+ (M), places the upper 32 bits of the
+ result in the destination register,
+ both rs1 and rs2 are treated as
+ unsigned
+
+
+
+
+ MULHSU rd, rs1, rs2
+
+
+ rd = rs1 s*u rs2
+
+
+ (M), places the upper 32 bits of the
+ result in the destination register,
+ rs1 treated as signed, rs2 treated
+ as unsigned
+
+
+
+
+ DIV rd, rs1, rs2
+
+
+ rd = rs1 /s rs2
+
+
(M), signed integer division
+
+
+
+ DIVU rd, rs1, rs2
+
+
+ rd = rs1 /u rs2
+
+
(M), unsigned integer division
+
+
+
+ REM rd, rs1, rs2
+
+
+ rd = rs1 %s rs2
+
+
+ (M), remainder of signed integer
+ division
+
+
+
+
+ REMU rd, rs1, rs2
+
+
+ rd = rs1 %u rs2
+
+
+ (M), remainder of unsigned integer
+ division
+
+
+
+
+
+
+ Note: Instructions marked with (M) are part of the
+ "M" Standard Extension for Integer Multiplication
+ and Division.
+
+
+
+
+
+
+
+
+
+
+
+ Unless otherwise specified, the immediate
+ (imm) has a length of 12 bits and is
+ sign extended to 32 bits.
+
+ var is a variable name,
+ index is an optional array index.
+
+ Jump and link register.
+ rd is set to the
+ address of the instruction following
+ the jump. The jump target is
+ rs1 + imm
+ with the least significant bit
+ cleared.
+
+ The immediate (imm) has a length of 20
+ bits and is sign extended to 32 bits.
+
+
+
-
-
- if (rs1 >=u rs2) PC = PC + imm
-
-
Branch if greater than or equal (unsigned)
-
-
-
-
-
-
U-Type
-
- The immediate (imm) has a length of 20 bits and is sign
- extended to 32 bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- LUI rd, imm
-
-
- rd = imm << 12
-
-
-
-
-
- AUIPC rd, imm
-
-
- rd = PC + (imm << 12)
-
-
-
-
-
-
-
-
J-Type
-
- The address to jump to (addr), is encoded relative to
- the current pc in a 21 bit immediate that is sign extended to 32
- bits and added to the current pc.
- Offsets are optional, and in hexadecimal format.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- JAL rd, addr
- JAL rd, label+offset
+
+
Instruction
+
Operation
+
Notes
+
+
+
+
+
+ LUI rd, imm
+
+
+ rd = imm << 12
+
+
+
+
+
+ AUIPC rd, imm
+
+
+ rd = PC + (imm <<
+ 12)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The address to jump to (addr), is
+ encoded relative to the current pc in a 21 bit
+ immediate that is sign extended to 32 bits and added
+ to the current pc.
+ Offsets are optional, and in hexadecimal format.
+
+
+
-
-
- rd = PC + 4; PC = addr
-
-
- Jump and link.
- rd is set to the address of the
- instruction following the jump.
-
-
-
-
-
+
+
+
Instruction
+
Operation
+
Notes
+
+
+
+
+
+ JAL rd, addr
+ JAL rd, label+offset
+
+
+ rd = PC + 4; PC = addr
+
+
+ Jump and link.
+ rd is set to the
+ address of the instruction following
+ the jump.
+
+
+
+
+
+
+
+
+
CSR-Type
Currently not implemented in 5-stage pipeline mode.
From bb5b6929b9382d827e8c4fc5c955af425b020178 Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Thu, 25 Apr 2024 17:36:22 +0200
Subject: [PATCH 055/138] more collapsibles
---
webgui/src/components/riscv/RiscvHelp.vue | 447 +++++++++++++---------
1 file changed, 267 insertions(+), 180 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index d05c360..e35a4bc 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -891,190 +891,277 @@
-
-
CSR-Type
-
- Currently not implemented in 5-stage pipeline mode.
-
- The unsigned immediate (uimm) has a length of 5
- bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- CSRRW rd, csr, rs1
-
-
- rd = csr; csr = rs1
-
-
Atomic read/write
-
-
-
- CSRRS rd, csr, rs1
-
-
- rd = csr; csr = csr | rs1
-
-
- Atomic read/set.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRC rd, csr, rs1
-
-
- rd = csr; csr = csr & ~rs1
-
-
- Atomic read/clear.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRWI rd, csr, uimm
-
-
- rd = csr; csr = uimm
-
-
Atomic read/write
-
-
-
- CSRRSI rd, csr, uimm
-
-
- rd = csr; csr = csr | uimm
-
-
- Atomic read/set.
- uimm
- serves as a bit mask
-
-
-
-
- CSRRCI rd, csr, uimm
-
-
- rd = csr; csr = csr & ~uimm
-
-
- Atomic read/clear.
- uimm
- serves as a bit mask
-
-
-
-
+
+
+
+
+
+
+
+ Currently not implemented in 5-stage pipeline
+ mode.
+
+ The unsigned immediate (uimm) has a
+ length of 5 bits.
+
+
+
+
+
+
Instruction
+
Operation
+
Notes
+
+
+
+
+
+ CSRRW rd, csr, rs1
+
+
+ rd = csr; csr = rs1
+
+
Atomic read/write
+
+
+
+ CSRRS rd, csr, rs1
+
+
+ rd = csr; csr = csr | rs1
+
+
+ Atomic read/set.
+ rs1
+ serves as a bit mask
+
+
+
+
+ CSRRC rd, csr, rs1
+
+
+ rd = csr; csr = csr &
+ ~rs1
+
+
+ Atomic read/clear.
+ rs1
+ serves as a bit mask
+
+
+
+
+ CSRRWI rd, csr, uimm
+
+
+ rd = csr; csr = uimm
+
+
Atomic read/write
+
+
+
+ CSRRSI rd, csr, uimm
+
+
+ rd = csr; csr = csr |
+ uimm
+
+
+ Atomic read/set.
+ uimm
+ serves as a bit mask
+
+
+
+
+ CSRRCI rd, csr, uimm
+
+
+ rd = csr; csr = csr &
+ ~uimm
+
+
+ Atomic read/clear.
+ uimm
+ serves as a bit mask
+
+
+
+
+
+
+
-
-
Pseudoinstructions
-
- var is a variable name, index is an
- optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- NOP
-
-
-
-
- No operation. Translated to
- ADDI x0, x0, 0
-
-
-
-
- LA rd, var[index]
-
-
- rd = &var[index]
-
-
- Load variable address into
- rd
-
-
-
-
- LI rd, imm
-
-
- rd = imm
-
-
- Load 32 bit immediate into
- rd
-
-
-
-
- MV rd, rs
-
-
rd = rs
-
- Translated to
- ADDI rd, rs, 0
-
-
-
-
+
+
+
+
+
+
+
+ var is a variable name,
+ index is an optional array index.
+
- Comments can be added to the code using
- #.
- Labels are added by appending a colon
- : to a label name. They can be used as jump targets.
-
-
+
Other
+
+
+
+
+
+
+
+
+
+ Comments can be added to the code using
+ #.
+ Labels are added by appending a colon
+ : to a label name. They can be used as
+ jump targets.
+
+
# This is a comment
my_label:
addi x1, x1, 1
jal x2, my_label
addi x3, x3, 1 # This line is never reached
-
-
Segments and variables
-
- In addition to the program code, the simulator supports a data
- segment. It can be used to store variables and arrays in the
- simulator's memory.
-
-
- In order to define a data segment, the
- .data directive is used, while the
- .text directive designates the code segment.
-
-
- The following example demonstrates how to declare and use variables
- and arrays, employing all currently supported data types. Note that
- all variables/arrays are word-aligned (addresses are multiples of
- 4), which is achieved by zero-padding preceding variables.
-
-
+ >
+
+
+
+
+
+
+
+
+
+
+ In addition to the program code, the simulator
+ supports a data segment. It can be used to store
+ variables and arrays in the simulator's memory.
+
+
+ In order to define a data segment, the
+ .data directive is used, while the
+ .text directive designates the code
+ segment.
+
+
+ The following example demonstrates how to declare
+ and use variables and arrays, employing all
+ currently supported data types. Note that all
+ variables/arrays are word-aligned (addresses are
+ multiples of 4), which is achieved by zero-padding
+ preceding variables.
+
+
.data
empty_array: .zero 64 # reserves space for 64 words (256 bytes)
# The following two declarations of 'my_var1' are equivalent,
@@ -1212,146 +1256,228 @@ addi x3, x3, 1 # This line is never reached
-
- If no directives are given, the entire input is interpreted as
- code.
- Similarly, if a .data but no
- .text directive is given, every line before the data
- segment is interpreted as code.
-
- There is no fixed segmentation order. However, declaring multiple
- segments of the same type will throw an error.
-
-
-
Cache Simulation
-
- You can activate separate caches for data and instructions in the
- settings. These caches can be configured as Write-through with Write
- no-allocate or Write-back with Write allocate. The number of sets,
- block size and associativity are also configurable. You can also
- choose between LRU and PLRU for the replacement strategy.
-
-
- As the name implies, LRU (Least Recently Used) will always replace
- the block that was used least recently. The LRU value in the cache
- table shows the age of each block. Higher values indicate more
- recently used blocks.
-
-
- PLRU (Pseudo LRU) is an approximation of LRU which is easier to
- implement in hardware. It uses a binary tree with the blocks at its
- leaf nodes. On each non-leaf node is a single bit - a 0 indicates
- that older blocks are in the upper child tree while a 1 indicates
- that older blocks are in the lower child tree.
- When replacing a block, PLRU will choose the one which is oldest
- according to those bits. Then all bits along the path are flipped to
- mark it as the most recent.
- When accessing any block that is stored in the cache, PLRU will
- update all bits along the path to the new block so they correctly
- identify it as the newest block.
- Note that when using PLRU, associativity must be a power of 2 since
- PLRU uses a binary tree in its state.
-
-
- You can also get a visualization of the cache by selecting it in the
- drop down menu in the control bar. Note that for performance
- reasons, this option becomes unavailabe if the cache gets too big.
- Even with the visualization disabled, you should not make the cache
- too big since the site may become unresponsive.
-
-
- When using a data cache, misaligned access to the memory is not
- allowed because it would be unclear what exactly should happen in
- the cache. For example, the following piece of code would not work
- since the accessed value crosses a word boundary:
-
-
lw x1, -5(x0)
-
-
ECALLs
-
- Environment calls (ECALLs) can be used for interacting with the
- environment - currently, ECALLs can be used for printing to the
- console or stopping the simulation. Each ECALL has a different code
- which must be loaded into register a7. Some ECALLs also
- require an argument which must be loaded into register
- a0. The supported ECALLs are identical to those of
- Ripes.
-
+ >
+
+ If no directives are given, the entire input is
+ interpreted as code.
+ Similarly, if a .data but no
+ .text directive is given, every line
+ before the data segment is interpreted as code.
+
+ There is no fixed segmentation order. However,
+ declaring multiple segments of the same type will
+ throw an error.
+
+
+
+
+
+
+
+
+
+
+
+ You can activate separate caches for data and
+ instructions in the settings. These caches can be
+ configured as Write-through with Write no-allocate
+ or Write-back with Write allocate. The number of
+ sets, block size and associativity are also
+ configurable. You can also choose between LRU and
+ PLRU for the replacement strategy.
+
+
+ As the name implies, LRU (Least Recently Used) will
+ always replace the block that was used least
+ recently. The LRU value in the cache table shows the
+ age of each block. Higher values indicate more
+ recently used blocks.
+
+
+ PLRU (Pseudo LRU) is an approximation of LRU which
+ is easier to implement in hardware. It uses a binary
+ tree with the blocks at its leaf nodes. On each
+ non-leaf node is a single bit - a 0 indicates that
+ older blocks are in the upper child tree while a 1
+ indicates that older blocks are in the lower child
+ tree.
+ When replacing a block, PLRU will choose the one
+ which is oldest according to those bits. Then all
+ bits along the path are flipped to mark it as the
+ most recent.
+ When accessing any block that is stored in the
+ cache, PLRU will update all bits along the path to
+ the new block so they correctly identify it as the
+ newest block.
+ Note that when using PLRU, associativity must be a
+ power of 2 since PLRU uses a binary tree in its
+ state.
+
+
+ You can also get a visualization of the cache by
+ selecting it in the drop down menu in the control
+ bar. Note that for performance reasons, this option
+ becomes unavailabe if the cache gets too big. Even
+ with the visualization disabled, you should not make
+ the cache too big since the site may become
+ unresponsive.
+
+
+ When using a data cache, misaligned access to the
+ memory is not allowed because it would be unclear
+ what exactly should happen in the cache. For
+ example, the following piece of code would not work
+ since the accessed value crosses a word boundary:
+
+
lw x1, -5(x0)
+
+
+
+
+
+
+
+
+
+
+ Environment calls (ECALLs) can be used for
+ interacting with the environment - currently, ECALLs
+ can be used for printing to the console or stopping
+ the simulation. Each ECALL has a different code
+ which must be loaded into register a7.
+ Some ECALLs also require an argument which must be
+ loaded into register a0. The supported
+ ECALLs are identical to those of Ripes.
+
-
- Note that our visualization of the pipeline during an ECALL is not
- fully correct. The pipeline might get flushed unnecessarily and we
- also dont halt the pipeline until the ECALL has finished - instead,
- the entire ecall is being executed in a single cycle (in the execute
- stage).
-
+
+ Note that our visualization of the pipeline during
+ an ECALL is not fully correct. The pipeline might
+ get flushed unnecessarily and we also dont halt the
+ pipeline until the ECALL has finished - instead, the
+ entire ecall is being executed in a single cycle (in
+ the execute stage).
+
-
-
-
-
-
a7
-
a0
-
Description
-
-
-
-
-
1
-
integer to print
-
Prints a0 as signed integer.
-
-
-
2
-
float to print
-
- Prints a0 as a floating point number.
-
-
-
-
4
-
string to print
-
- Prints the null terminated string whose first
- character is stored at the address in
- a0.
-
-
-
-
10
-
-
-
Stops the simulation with code 0.
-
-
-
11
-
char to print
-
Prints a0 as ASCII character
-
-
-
34
-
hex to print
-
Prints a0 as hexadecimal nuber
-
-
-
35
-
binary to print
-
Prints a0 as binary number.
-
-
-
36
-
integer to print
-
Prints a0 as unsigned integer.
-
-
-
93
-
exit code
-
- Stops the simulation with code in a0.
-
-
-
-
+
+
+
+
+
a7
+
a0
+
Description
+
+
+
+
+
1
+
integer to print
+
+ Prints a0 as signed
+ integer.
+
+
+
+
2
+
float to print
+
+ Prints a0 as a floating
+ point number.
+
+
+
+
4
+
string to print
+
+ Prints the null terminated string
+ whose first character is stored at
+ the address in
+ a0.
+
+
+
+
10
+
-
+
+ Stops the simulation with code 0.
+
+
+
+
11
+
char to print
+
+ Prints a0 as ASCII
+ character
+
+
+
+
34
+
hex to print
+
+ Prints a0 as
+ hexadecimal nuber
+
+
+
+
35
+
binary to print
+
+ Prints a0 as binary
+ number.
+
+
+
+
36
+
integer to print
+
+ Prints a0 as unsigned
+ integer.
+
+
+
+
93
+
exit code
+
+ Stops the simulation with code in
+ a0.
+
+
+
+
+
+
+
+
+
From f101b2f24bd042427c5d34ea900a4653a11b197f Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Thu, 25 Apr 2024 19:15:04 +0200
Subject: [PATCH 057/138] finish accordion riscv help page
---
webgui/src/components/riscv/RiscvHelp.vue | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index f8e53b0..c2b16dc 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -7,8 +7,8 @@
This simulator supports a subset of the RISC-V32 ISA. The supported
instructions are listed below.
-
-
+
+
-
-
Other
-
-
+
+
Other
+
+
@@ -1479,5 +1480,4 @@ addi x3, x3, 1 # This line is never reached
-
From 96ca224985829305125cd4353216119e6771ed05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 09:32:39 +0200
Subject: [PATCH 058/138] Added a test for the bug
---
tests/test_riscv_pipeline.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tests/test_riscv_pipeline.py b/tests/test_riscv_pipeline.py
index 881a5b1..39215b5 100644
--- a/tests/test_riscv_pipeline.py
+++ b/tests/test_riscv_pipeline.py
@@ -1418,3 +1418,19 @@ def test_stall_2(self):
self.assertEqual(sim.state.performance_metrics.cycles, 14)
self.assertEqual(sim.state.performance_metrics.stalls, 2)
self.assertEqual(sim.state.performance_metrics.flushes, 0)
+
+ def test_exit(self):
+ program = """li a7, 10
+ ecall
+ nop
+ nop
+ nop
+ nop
+ nop"""
+
+ sim = RiscvSimulation(mode="five_stage_pipeline")
+
+ sim.load_program(program)
+ sim.run()
+ self.assertEqual(sim.state.performance_metrics.cycles, 8)
+ self.assertEqual(sim.state.performance_metrics.instruction_count, 2)
From 5798b24672f0dc3609fac9ccdea23f201235d697 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 10:15:57 +0200
Subject: [PATCH 059/138] Ecall now continues until the wb stage But it doesn't
flush yet, which is not good
---
.../isa/riscv/rv32i_instructions.py | 42 +++++++++++++------
.../uarch/riscv/pipeline_registers.py | 2 +
architecture_simulator/uarch/riscv/stages.py | 28 +++++++++----
3 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/architecture_simulator/isa/riscv/rv32i_instructions.py b/architecture_simulator/isa/riscv/rv32i_instructions.py
index fdb224f..2c925a8 100644
--- a/architecture_simulator/isa/riscv/rv32i_instructions.py
+++ b/architecture_simulator/isa/riscv/rv32i_instructions.py
@@ -825,38 +825,56 @@ def behavior(
self, architectural_state: RiscvArchitecturalState
) -> RiscvArchitecturalState:
"""RaiseException(EnvironmentCall)"""
+ result = self.process_ecall(architectural_state)
+ if type(result) is int:
+ architectural_state.exit_code = result
+ elif type(result) is str:
+ architectural_state.output += result
+ return architectural_state
+
+ def process_ecall(self, architectural_state: RiscvArchitecturalState) -> str | int:
+ """Processes this ecall. Returns the action to be applied to the architectural state.
+
+ Args:
+ architectural_state (RiscvArchitecturalState): The state on which the ecall shall be applied.
+
+ Raises:
+ ValueError: Raises an error if the ECALL code is invalid.
+
+ Returns:
+ str|int: Returns either a string to be printed to the output or an exit code.
+ """
code = int(architectural_state.register_file.registers[17])
arg = int(architectural_state.register_file.registers[10])
match code:
case 1: # print arg as sint
- architectural_state.output += str(fixedint.Int32(arg))
+ return str(fixedint.Int32(arg))
case 2: # print arg as 32-bit float
- architectural_state.output += str(
- unpack(">f", arg.to_bytes(4, "big"))[0]
- )
+ return str(unpack(">f", arg.to_bytes(4, "big"))[0])
case 4: # print null-terminated string stored at address in arg
address = arg
+ result = ""
while (
byte := architectural_state.memory.read_byte(address, False)
) != 0:
- architectural_state.output += chr(byte % 128)
+ result += chr(byte % 128)
address += 1
+ return result
case 11: # print arg as ascii char
- architectural_state.output += chr(arg % 128)
+ return chr(arg % 128)
case 34: # print arg as hex
- architectural_state.output += "0x" + "{:X}".format(arg)
+ return "0x" + "{:X}".format(arg)
case 35: # print arg as bin
- architectural_state.output += bin(arg)
+ return bin(arg)
case 36: # print arg as uint
- architectural_state.output += str(arg)
+ return str(arg)
case 10: # exit with status 0
- architectural_state.exit_code = 0
+ return 0
case 93: # exit with arg as status
- architectural_state.exit_code = arg
+ return arg
case _:
raise ValueError(f"{code} (register a7) is not a valid code for ECALL")
- return architectural_state
def alu_compute(
self, alu_in_1: int | None, alu_in_2: int | None
diff --git a/architecture_simulator/uarch/riscv/pipeline_registers.py b/architecture_simulator/uarch/riscv/pipeline_registers.py
index 71dd00e..1f49d7d 100644
--- a/architecture_simulator/uarch/riscv/pipeline_registers.py
+++ b/architecture_simulator/uarch/riscv/pipeline_registers.py
@@ -63,6 +63,7 @@ class ExecutePipelineRegister(PipelineRegister):
pc_plus_imm: Optional[int] = None
branch_prediction: Optional[bool] = None
pc_plus_instruction_length: Optional[int] = None
+ exit_code: Optional[int] = None
abbreviation = "EX"
@@ -80,6 +81,7 @@ class MemoryAccessPipelineRegister(PipelineRegister):
pc_plus_imm: Optional[int] = None
pc_plus_instruction_length: Optional[int] = None
imm: Optional[int] = None
+ exit_code: Optional[int] = None
abbreviation = "MEM"
diff --git a/architecture_simulator/uarch/riscv/stages.py b/architecture_simulator/uarch/riscv/stages.py
index 2d724f6..f1944ad 100644
--- a/architecture_simulator/uarch/riscv/stages.py
+++ b/architecture_simulator/uarch/riscv/stages.py
@@ -237,6 +237,7 @@ def behavior(
# ECALL needs some special behavior (flush and print to output)
stall_signal = None
+ exit_code = None
if isinstance(pipeline_register.instruction, ECALL):
# assume that all further stages need to be empty, unless this stage is already stalled and the value of the next register is only for display purposes
for other_pr in pipeline_registers[
@@ -249,7 +250,11 @@ def behavior(
stall_signal = StallSignal(2)
break
if stall_signal is None:
- pipeline_register.instruction.behavior(state)
+ ecall_result = pipeline_register.instruction.process_ecall(state)
+ if type(ecall_result) is str:
+ state.output += ecall_result
+ elif type(ecall_result) is int:
+ exit_code = ecall_result
return ExecutePipelineRegister(
stall_signal=stall_signal,
@@ -267,6 +272,7 @@ def behavior(
branch_prediction=pipeline_register.branch_prediction,
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
address_of_instruction=pipeline_register.address_of_instruction,
+ exit_code=exit_code,
)
@@ -349,6 +355,7 @@ def behavior(
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
imm=pipeline_register.imm,
address_of_instruction=pipeline_register.address_of_instruction,
+ exit_code=pipeline_register.exit_code,
)
@@ -402,6 +409,9 @@ def behavior(
architectural_state=state,
)
+ if pipeline_register.exit_code is not None:
+ state.exit_code = pipeline_register.exit_code
+
return RegisterWritebackPipelineRegister(
instruction=pipeline_register.instruction,
register_write_data=register_write_data,
@@ -504,12 +514,16 @@ def behavior(
result_pr.pc_plus_imm = state.program_counter + result_pr.imm
a_comparison, a_result = result_pr.instruction.alu_compute(
- state.program_counter
- if result_pr.control_unit_signals.alu_src_1
- else result_pr.register_read_data_1,
- result_pr.imm
- if result_pr.control_unit_signals.alu_src_2
- else result_pr.register_read_data_2,
+ (
+ state.program_counter
+ if result_pr.control_unit_signals.alu_src_1
+ else result_pr.register_read_data_1
+ ),
+ (
+ result_pr.imm
+ if result_pr.control_unit_signals.alu_src_2
+ else result_pr.register_read_data_2
+ ),
)
result_pr.alu_comparison = bool(a_comparison)
From 9882dd8d39ef7cd93b79776611eedc8d787f8d68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 10:19:09 +0200
Subject: [PATCH 060/138] Added a test for flushing
---
tests/test_riscv_pipeline.py | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/tests/test_riscv_pipeline.py b/tests/test_riscv_pipeline.py
index 39215b5..d3412b2 100644
--- a/tests/test_riscv_pipeline.py
+++ b/tests/test_riscv_pipeline.py
@@ -1419,7 +1419,7 @@ def test_stall_2(self):
self.assertEqual(sim.state.performance_metrics.stalls, 2)
self.assertEqual(sim.state.performance_metrics.flushes, 0)
- def test_exit(self):
+ def test_exit_1(self):
program = """li a7, 10
ecall
nop
@@ -1434,3 +1434,19 @@ def test_exit(self):
sim.run()
self.assertEqual(sim.state.performance_metrics.cycles, 8)
self.assertEqual(sim.state.performance_metrics.instruction_count, 2)
+
+ def test_exit_2(self):
+ # make sure instructions are flushed to prevent unwanted "side effects"
+ program = """li x3, 555
+li a7, 10
+ecall
+sw x3, -4(x0)
+nop
+nop"""
+ sim = RiscvSimulation(mode="five_stage_pipeline")
+
+ sim.load_program(program)
+ sim.run()
+ self.assertEqual(sim.state.performance_metrics.cycles, 9)
+ self.assertEqual(sim.state.performance_metrics.instruction_count, 3)
+ self.assertEqual(sim.state.memory.read_word(-4, False), 0)
From 00fe3e6afa5d7f3b8e0fe81dbaa0b72be4752f46 Mon Sep 17 00:00:00 2001
From: Michael Kuhn
Date: Fri, 26 Apr 2024 10:45:49 +0200
Subject: [PATCH 061/138] generate riscv instruction table from json data
---
webgui/src/components/riscv/RiscvHelp.vue | 39 +++
webgui/src/data/riscv_instructions.json | 338 ++++++++++++++++++++++
2 files changed, 377 insertions(+)
create mode 100644 webgui/src/data/riscv_instructions.json
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index c2b16dc..e472e3f 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -8,6 +8,25 @@
instructions are listed below.
+
+
+
+
+
+ {{ field }}
+
+
+
+
+
+
+
+ {{ item[field] }}
+
+
+
+
+
@@ -1481,3 +1500,23 @@ addi x3, x3, 1 # This line is never reached
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
new file mode 100644
index 0000000..1bb548c
--- /dev/null
+++ b/webgui/src/data/riscv_instructions.json
@@ -0,0 +1,338 @@
+[
+ {
+ "Instruction":"ADD rd, rs1, rs2",
+ "Operation":"rd = rs1 + rs2",
+ "Notes":null,
+ "Format":"R-type"
+ },
+ {
+ "Instruction":"SUB rd, rs1, rs2",
+ "Operation":"rd = rs1 - rs2",
+ "Notes":null,
+ "Format":"R-type"
+ },
+ {
+ "Instruction":"SLL rd, rs1, rs2",
+ "Operation":"rd = rs1 << rs2",
+ "Notes":null,
+ "Format":"R-type"
+ },
+ {
+ "Instruction":"SRL rd, rs1, rs2",
+ "Operation":"rd = rs1 >> rs2",
+ "Notes":"Logical right shift",
+ "Format":"R-type"
+ },
+ {
+ "Instruction":"SRA rd, rs1, rs2",
+ "Operation":"rd = rs1 >>a rs2",
+ "Notes":"Arithmetic right shift",
+ "Format":"R-type"
+ },
+ {
+ "Instruction":"SLT rd, rs1, rs2",
+ "Operation":"rd = rs1 > imm",
+ "Notes":"Logical right shift. imm is unsigned, with a length of 5 bits",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"SRAI rd, rs1, imm",
+ "Operation":"rd = rs1 >>a imm",
+ "Notes":"Arithmetic right shift. imm is unsigned, with a length of 5 bits",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"LB rd, rs1, imm LB rd, imm(rs1) LB rd, var[index]",
+ "Operation":"rd = M[rs1 + imm] rd = var[index]",
+ "Notes":"Load byte. rd is sign extended to 32 bits",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"LH rd, rs1, imm LH rd, imm(rs1) LH rd, var[index]",
+ "Operation":"rd = M[rs1 + imm] rd = var[index]",
+ "Notes":"Load two bytes. rd is sign extended to 32 bits",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"LW rd, rs1, imm LW rd, imm(rs1) LW rd, var[index]",
+ "Operation":"rd = M[rs1 + imm] rd = var[index]",
+ "Notes":"Load four bytes. rd is sign extended to 32 bits",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"LBU rd, rs1, imm LBU rd, imm(rs1) LBU rd, var[index]",
+ "Operation":"rd = M[rs1 + imm] rd = var[index]",
+ "Notes":"Load byte",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"LHU rd, rs1, imm LHU rd, imm(rs1) LHU rd, var[index]",
+ "Operation":"rd = M[rs1 + imm] rd = var[index]",
+ "Notes":"Load two bytes",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"JALR rd, rs1, imm",
+ "Operation":"rd = PC + 4; PC = rs1 + imm",
+ "Notes":"Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"ECALL",
+ "Operation":"environment call",
+ "Notes":"See section ECALLs.",
+ "Format":"I-type"
+ },
+ {
+ "Instruction":"SB rs1, rs2, imm SB rs1, imm(rs2) SB rs1, var[index], rs2",
+ "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes":"Store byte. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format":"S-type"
+ },
+ {
+ "Instruction":"SH rs1, rs2, imm SH rs1, imm(rs2) SH rs1, var[index], rs2",
+ "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes":"Store two bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format":"S-type"
+ },
+ {
+ "Instruction":"SW rs1, rs2, imm SW rs1, imm(rs2) SW rs1, var[index], rs2",
+ "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes":"Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format":"S-type"
+ },
+ {
+ "Instruction":"BEQ rs1, rs2, imm BEQ rs1, rs2, label+offset",
+ "Operation":"if (rs1 == rs2) PC = PC + imm",
+ "Notes":"Branch if equal",
+ "Format":"B-type"
+ },
+ {
+ "Instruction":"BNE rs1, rs2, imm BNE rs1, rs2, label+offset",
+ "Operation":"if (rs1 != rs2) PC = PC + imm",
+ "Notes":"Branch if not equal",
+ "Format":"B-type"
+ },
+ {
+ "Instruction":"BLT rs1, rs2, imm BLT rs1, rs2, label+offset",
+ "Operation":"if (rs1 =s rs2) PC = PC + imm",
+ "Notes":"Branch if greater than or equal",
+ "Format":"B-type"
+ },
+ {
+ "Instruction":"BLTU rs1, rs2, imm BLTU rs1, rs2, label+offset",
+ "Operation":"if (rs1 =u rs2) PC = PC + imm",
+ "Notes":"Branch if greater than or equal (unsigned)",
+ "Format":"B-type"
+ },
+ {
+ "Instruction":"LUI rd, imm",
+ "Operation":"rd = imm << 12",
+ "Notes":null,
+ "Format":"U"
+ },
+ {
+ "Instruction":"AUIPC rd, imm",
+ "Operation":"rd = PC + (imm << 12)",
+ "Notes":null,
+ "Format":"U"
+ },
+ {
+ "Instruction":"JAL rd, addr JAL rd, label+offset",
+ "Operation":"rd = PC + 4; PC = addr",
+ "Notes":"Jump and link. rd is set to the address of the instruction following the jump.",
+ "Format":"J-type"
+ },
+ {
+ "Instruction":"CSRRW rd, csr, rs1",
+ "Operation":"rd = csr; csr = rs1",
+ "Notes":"Atomic read\/write",
+ "Format":"CSR"
+ },
+ {
+ "Instruction":"CSRRS rd, csr, rs1",
+ "Operation":"rd = csr; csr = csr | rs1",
+ "Notes":"Atomic read\/set. rs1 serves as a bit mask",
+ "Format":"CSR"
+ },
+ {
+ "Instruction":"CSRRC rd, csr, rs1",
+ "Operation":"rd = csr; csr = csr & ~rs1",
+ "Notes":"Atomic read\/clear. rs1 serves as a bit mask",
+ "Format":"CSR"
+ },
+ {
+ "Instruction":"CSRRWI rd, csr, uimm",
+ "Operation":"rd = csr; csr = uimm",
+ "Notes":"Atomic read\/write",
+ "Format":"CSR"
+ },
+ {
+ "Instruction":"CSRRSI rd, csr, uimm",
+ "Operation":"rd = csr; csr = csr | uimm",
+ "Notes":"Atomic read\/set. uimm serves as a bit mask",
+ "Format":"CSR"
+ },
+ {
+ "Instruction":"CSRRCI rd, csr, uimm",
+ "Operation":"rd = csr; csr = csr & ~uimm",
+ "Notes":"Atomic read\/clear. uimm serves as a bit mask",
+ "Format":"CSR"
+ },
+ {
+ "Instruction":"NOP",
+ "Operation":"-",
+ "Notes":"No operation. Translated to ADDI x0, x0, 0",
+ "Format":"Pseudo"
+ },
+ {
+ "Instruction":"LA rd, var[index]",
+ "Operation":"rd = &var[index]",
+ "Notes":"Load variable address into rd",
+ "Format":"Pseudo"
+ },
+ {
+ "Instruction":"LI rd, imm",
+ "Operation":"rd = imm",
+ "Notes":"Load 32 bit immediate into rd",
+ "Format":"Pseudo"
+ },
+ {
+ "Instruction":"MV rd, rs",
+ "Operation":"rd = rs",
+ "Notes":"Translated to ADDI rd, rs, 0",
+ "Format":"Pseudo"
+ }
+]
From 7b4132d81f3c843f93a0f89f7c317c03c35552f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 10:53:44 +0200
Subject: [PATCH 062/138] Added flushes for ecall exit
---
architecture_simulator/uarch/riscv/stages.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/architecture_simulator/uarch/riscv/stages.py b/architecture_simulator/uarch/riscv/stages.py
index f1944ad..023de5a 100644
--- a/architecture_simulator/uarch/riscv/stages.py
+++ b/architecture_simulator/uarch/riscv/stages.py
@@ -238,6 +238,7 @@ def behavior(
# ECALL needs some special behavior (flush and print to output)
stall_signal = None
exit_code = None
+ flush_signal = None # Needed for exiting the simulation (ecall 10/93)
if isinstance(pipeline_register.instruction, ECALL):
# assume that all further stages need to be empty, unless this stage is already stalled and the value of the next register is only for display purposes
for other_pr in pipeline_registers[
@@ -255,6 +256,10 @@ def behavior(
state.output += ecall_result
elif type(ecall_result) is int:
exit_code = ecall_result
+ assert pipeline_register.pc_plus_instruction_length is not None
+ flush_signal = FlushSignal(
+ False, pipeline_register.pc_plus_instruction_length
+ )
return ExecutePipelineRegister(
stall_signal=stall_signal,
@@ -273,6 +278,7 @@ def behavior(
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
address_of_instruction=pipeline_register.address_of_instruction,
exit_code=exit_code,
+ flush_signal=flush_signal,
)
@@ -331,6 +337,12 @@ def behavior(
flush_signal = FlushSignal(
inclusive=False, address=pipeline_register.result
)
+ elif pipeline_register.exit_code is not None:
+ # Exit codes stem from ecalls which cannot cause branches and thus cannot generate other flush signals
+ assert pipeline_register.pc_plus_instruction_length is not None
+ flush_signal = FlushSignal(
+ False, pipeline_register.pc_plus_instruction_length
+ )
else:
flush_signal = None
@@ -409,7 +421,12 @@ def behavior(
architectural_state=state,
)
+ flush_signal = None
if pipeline_register.exit_code is not None:
+ assert pipeline_register.pc_plus_instruction_length is not None
+ flush_signal = FlushSignal(
+ False, pipeline_register.pc_plus_instruction_length
+ )
state.exit_code = pipeline_register.exit_code
return RegisterWritebackPipelineRegister(
@@ -422,6 +439,7 @@ def behavior(
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
imm=pipeline_register.imm,
address_of_instruction=pipeline_register.address_of_instruction,
+ flush_signal=flush_signal,
)
From 5d8b19e700958c34cb7d5c5450d5cfa512db60ce Mon Sep 17 00:00:00 2001
From: Michael Kuhn
Date: Fri, 26 Apr 2024 11:18:55 +0200
Subject: [PATCH 063/138] format riscv help table
---
webgui/src/components/riscv/RiscvHelp.vue | 10 +++++++-
webgui/src/data/riscv_instructions.json | 30 +++++++++++------------
2 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index e472e3f..92266c9 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -21,7 +21,15 @@
- {{ item[field] }}
+
+ {{ item[field] }}
+
+
{{ item[field] }}
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index 1bb548c..9c8d4a3 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -162,31 +162,31 @@
"Format":"I-type"
},
{
- "Instruction":"LB rd, rs1, imm LB rd, imm(rs1) LB rd, var[index]",
+ "Instruction":"LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
"Operation":"rd = M[rs1 + imm] rd = var[index]",
"Notes":"Load byte. rd is sign extended to 32 bits",
"Format":"I-type"
},
{
- "Instruction":"LH rd, rs1, imm LH rd, imm(rs1) LH rd, var[index]",
+ "Instruction":"LH rd, rs1, imm\nLH rd, imm(rs1)\nLH rd, var[index]",
"Operation":"rd = M[rs1 + imm] rd = var[index]",
"Notes":"Load two bytes. rd is sign extended to 32 bits",
"Format":"I-type"
},
{
- "Instruction":"LW rd, rs1, imm LW rd, imm(rs1) LW rd, var[index]",
+ "Instruction":"LW rd, rs1, imm\nLW rd, imm(rs1)\nLW rd, var[index]",
"Operation":"rd = M[rs1 + imm] rd = var[index]",
"Notes":"Load four bytes. rd is sign extended to 32 bits",
"Format":"I-type"
},
{
- "Instruction":"LBU rd, rs1, imm LBU rd, imm(rs1) LBU rd, var[index]",
+ "Instruction":"LBU rd, rs1, imm\nLBU rd, imm(rs1)\nLBU rd, var[index]",
"Operation":"rd = M[rs1 + imm] rd = var[index]",
"Notes":"Load byte",
"Format":"I-type"
},
{
- "Instruction":"LHU rd, rs1, imm LHU rd, imm(rs1) LHU rd, var[index]",
+ "Instruction":"LHU rd, rs1, imm\nLHU rd, imm(rs1)\nLHU rd, var[index]",
"Operation":"rd = M[rs1 + imm] rd = var[index]",
"Notes":"Load two bytes",
"Format":"I-type"
@@ -204,55 +204,55 @@
"Format":"I-type"
},
{
- "Instruction":"SB rs1, rs2, imm SB rs1, imm(rs2) SB rs1, var[index], rs2",
+ "Instruction":"SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
"Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
"Notes":"Store byte. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format":"S-type"
},
{
- "Instruction":"SH rs1, rs2, imm SH rs1, imm(rs2) SH rs1, var[index], rs2",
+ "Instruction":"SH rs1, rs2, imm\nSH rs1, imm(rs2)\nSH rs1, var[index], rs2",
"Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
"Notes":"Store two bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format":"S-type"
},
{
- "Instruction":"SW rs1, rs2, imm SW rs1, imm(rs2) SW rs1, var[index], rs2",
+ "Instruction":"SW rs1, rs2, imm\nSW rs1, imm(rs2)\nSW rs1, var[index], rs2",
"Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
"Notes":"Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format":"S-type"
},
{
- "Instruction":"BEQ rs1, rs2, imm BEQ rs1, rs2, label+offset",
+ "Instruction":"BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
"Operation":"if (rs1 == rs2) PC = PC + imm",
"Notes":"Branch if equal",
"Format":"B-type"
},
{
- "Instruction":"BNE rs1, rs2, imm BNE rs1, rs2, label+offset",
+ "Instruction":"BNE rs1, rs2, imm\nBNE rs1, rs2, label+offset",
"Operation":"if (rs1 != rs2) PC = PC + imm",
"Notes":"Branch if not equal",
"Format":"B-type"
},
{
- "Instruction":"BLT rs1, rs2, imm BLT rs1, rs2, label+offset",
+ "Instruction":"BLT rs1, rs2, imm\nBLT rs1, rs2, label+offset",
"Operation":"if (rs1 =s rs2) PC = PC + imm",
"Notes":"Branch if greater than or equal",
"Format":"B-type"
},
{
- "Instruction":"BLTU rs1, rs2, imm BLTU rs1, rs2, label+offset",
+ "Instruction":"BLTU rs1, rs2, imm\nBLTU rs1, rs2, label+offset",
"Operation":"if (rs1 =u rs2) PC = PC + imm",
"Notes":"Branch if greater than or equal (unsigned)",
"Format":"B-type"
@@ -270,7 +270,7 @@
"Format":"U"
},
{
- "Instruction":"JAL rd, addr JAL rd, label+offset",
+ "Instruction":"JAL rd, addr\nJAL rd, label+offset",
"Operation":"rd = PC + 4; PC = addr",
"Notes":"Jump and link. rd is set to the address of the instruction following the jump.",
"Format":"J-type"
From b777a5c4839e5ca25541b1ce8b46b97826605b34 Mon Sep 17 00:00:00 2001
From: Michael Kuhn
Date: Fri, 26 Apr 2024 11:31:24 +0200
Subject: [PATCH 064/138] complete instruction formats
---
webgui/src/data/riscv_instructions.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index 9c8d4a3..5af1f0e 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -261,13 +261,13 @@
"Instruction":"LUI rd, imm",
"Operation":"rd = imm << 12",
"Notes":null,
- "Format":"U"
+ "Format":"U-type"
},
{
"Instruction":"AUIPC rd, imm",
"Operation":"rd = PC + (imm << 12)",
"Notes":null,
- "Format":"U"
+ "Format":"U-type"
},
{
"Instruction":"JAL rd, addr\nJAL rd, label+offset",
From 763c453b77cdc5f6ab52d5a651fd202f75bb146a Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Fri, 26 Apr 2024 12:08:27 +0200
Subject: [PATCH 065/138] put tables into component
---
webgui/src/components/riscv/RiscvHelp.vue | 52 +-
.../src/components/riscv/RiscvHelpTable.vue | 28 +
webgui/src/data/riscv_instructions.json | 679 +++++++++---------
3 files changed, 375 insertions(+), 384 deletions(-)
create mode 100644 webgui/src/components/riscv/RiscvHelpTable.vue
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index 92266c9..d694144 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -1,4 +1,9 @@
+
RISC-V
@@ -8,32 +13,7 @@
instructions are listed below.
-
-
-
-
-
- {{ field }}
-
-
-
-
-
-
-
-
- {{ item[field] }}
-
-
{{ item[field] }}
-
-
-
-
+
@@ -1508,23 +1488,3 @@ addi x3, x3, 1 # This line is never reached
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index 9c8d4a3..ec98eaa 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -1,338 +1,341 @@
-[
- {
- "Instruction":"ADD rd, rs1, rs2",
- "Operation":"rd = rs1 + rs2",
- "Notes":null,
- "Format":"R-type"
- },
- {
- "Instruction":"SUB rd, rs1, rs2",
- "Operation":"rd = rs1 - rs2",
- "Notes":null,
- "Format":"R-type"
- },
- {
- "Instruction":"SLL rd, rs1, rs2",
- "Operation":"rd = rs1 << rs2",
- "Notes":null,
- "Format":"R-type"
- },
- {
- "Instruction":"SRL rd, rs1, rs2",
- "Operation":"rd = rs1 >> rs2",
- "Notes":"Logical right shift",
- "Format":"R-type"
- },
- {
- "Instruction":"SRA rd, rs1, rs2",
- "Operation":"rd = rs1 >>a rs2",
- "Notes":"Arithmetic right shift",
- "Format":"R-type"
- },
- {
- "Instruction":"SLT rd, rs1, rs2",
- "Operation":"rd = rs1 > imm",
- "Notes":"Logical right shift. imm is unsigned, with a length of 5 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"SRAI rd, rs1, imm",
- "Operation":"rd = rs1 >>a imm",
- "Notes":"Arithmetic right shift. imm is unsigned, with a length of 5 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load byte. rd is sign extended to 32 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LH rd, rs1, imm\nLH rd, imm(rs1)\nLH rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load two bytes. rd is sign extended to 32 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LW rd, rs1, imm\nLW rd, imm(rs1)\nLW rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load four bytes. rd is sign extended to 32 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LBU rd, rs1, imm\nLBU rd, imm(rs1)\nLBU rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load byte",
- "Format":"I-type"
- },
- {
- "Instruction":"LHU rd, rs1, imm\nLHU rd, imm(rs1)\nLHU rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load two bytes",
- "Format":"I-type"
- },
- {
- "Instruction":"JALR rd, rs1, imm",
- "Operation":"rd = PC + 4; PC = rs1 + imm",
- "Notes":"Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
- "Format":"I-type"
- },
- {
- "Instruction":"ECALL",
- "Operation":"environment call",
- "Notes":"See section ECALLs.",
- "Format":"I-type"
- },
- {
- "Instruction":"SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
- "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
- "Notes":"Store byte. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
- "Format":"S-type"
- },
- {
- "Instruction":"SH rs1, rs2, imm\nSH rs1, imm(rs2)\nSH rs1, var[index], rs2",
- "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
- "Notes":"Store two bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
- "Format":"S-type"
- },
- {
- "Instruction":"SW rs1, rs2, imm\nSW rs1, imm(rs2)\nSW rs1, var[index], rs2",
- "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
- "Notes":"Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
- "Format":"S-type"
- },
- {
- "Instruction":"BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
- "Operation":"if (rs1 == rs2) PC = PC + imm",
- "Notes":"Branch if equal",
- "Format":"B-type"
- },
- {
- "Instruction":"BNE rs1, rs2, imm\nBNE rs1, rs2, label+offset",
- "Operation":"if (rs1 != rs2) PC = PC + imm",
- "Notes":"Branch if not equal",
- "Format":"B-type"
- },
- {
- "Instruction":"BLT rs1, rs2, imm\nBLT rs1, rs2, label+offset",
- "Operation":"if (rs1 =s rs2) PC = PC + imm",
- "Notes":"Branch if greater than or equal",
- "Format":"B-type"
- },
- {
- "Instruction":"BLTU rs1, rs2, imm\nBLTU rs1, rs2, label+offset",
- "Operation":"if (rs1 =u rs2) PC = PC + imm",
- "Notes":"Branch if greater than or equal (unsigned)",
- "Format":"B-type"
- },
- {
- "Instruction":"LUI rd, imm",
- "Operation":"rd = imm << 12",
- "Notes":null,
- "Format":"U"
- },
- {
- "Instruction":"AUIPC rd, imm",
- "Operation":"rd = PC + (imm << 12)",
- "Notes":null,
- "Format":"U"
- },
- {
- "Instruction":"JAL rd, addr\nJAL rd, label+offset",
- "Operation":"rd = PC + 4; PC = addr",
- "Notes":"Jump and link. rd is set to the address of the instruction following the jump.",
- "Format":"J-type"
- },
- {
- "Instruction":"CSRRW rd, csr, rs1",
- "Operation":"rd = csr; csr = rs1",
- "Notes":"Atomic read\/write",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRS rd, csr, rs1",
- "Operation":"rd = csr; csr = csr | rs1",
- "Notes":"Atomic read\/set. rs1 serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRC rd, csr, rs1",
- "Operation":"rd = csr; csr = csr & ~rs1",
- "Notes":"Atomic read\/clear. rs1 serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRWI rd, csr, uimm",
- "Operation":"rd = csr; csr = uimm",
- "Notes":"Atomic read\/write",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRSI rd, csr, uimm",
- "Operation":"rd = csr; csr = csr | uimm",
- "Notes":"Atomic read\/set. uimm serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRCI rd, csr, uimm",
- "Operation":"rd = csr; csr = csr & ~uimm",
- "Notes":"Atomic read\/clear. uimm serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"NOP",
- "Operation":"-",
- "Notes":"No operation. Translated to ADDI x0, x0, 0",
- "Format":"Pseudo"
- },
- {
- "Instruction":"LA rd, var[index]",
- "Operation":"rd = &var[index]",
- "Notes":"Load variable address into rd",
- "Format":"Pseudo"
- },
- {
- "Instruction":"LI rd, imm",
- "Operation":"rd = imm",
- "Notes":"Load 32 bit immediate into rd",
- "Format":"Pseudo"
- },
- {
- "Instruction":"MV rd, rs",
- "Operation":"rd = rs",
- "Notes":"Translated to ADDI rd, rs, 0",
- "Format":"Pseudo"
- }
-]
+{
+ "all": [
+ {
+ "Instruction": "ADD rd, rs1, rs2",
+ "Operation": "rd = rs1 + rs2",
+ "Notes": null,
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SUB rd, rs1, rs2",
+ "Operation": "rd = rs1 - rs2",
+ "Notes": null,
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SLL rd, rs1, rs2",
+ "Operation": "rd = rs1 << rs2",
+ "Notes": null,
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SRL rd, rs1, rs2",
+ "Operation": "rd = rs1 >> rs2",
+ "Notes": "Logical right shift",
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SRA rd, rs1, rs2",
+ "Operation": "rd = rs1 >>a rs2",
+ "Notes": "Arithmetic right shift",
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SLT rd, rs1, rs2",
+ "Operation": "rd = rs1 > imm",
+ "Notes": "Logical right shift. imm is unsigned, with a length of 5 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "SRAI rd, rs1, imm",
+ "Operation": "rd = rs1 >>a imm",
+ "Notes": "Arithmetic right shift. imm is unsigned, with a length of 5 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load byte. rd is sign extended to 32 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LH rd, rs1, imm\nLH rd, imm(rs1)\nLH rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load two bytes. rd is sign extended to 32 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LW rd, rs1, imm\nLW rd, imm(rs1)\nLW rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load four bytes. rd is sign extended to 32 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LBU rd, rs1, imm\nLBU rd, imm(rs1)\nLBU rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load byte",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LHU rd, rs1, imm\nLHU rd, imm(rs1)\nLHU rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load two bytes",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "JALR rd, rs1, imm",
+ "Operation": "rd = PC + 4; PC = rs1 + imm",
+ "Notes": "Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "ECALL",
+ "Operation": "environment call",
+ "Notes": "See section ECALLs.",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
+ "Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes": "Store byte. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format": "S-type"
+ },
+ {
+ "Instruction": "SH rs1, rs2, imm\nSH rs1, imm(rs2)\nSH rs1, var[index], rs2",
+ "Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes": "Store two bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format": "S-type"
+ },
+ {
+ "Instruction": "SW rs1, rs2, imm\nSW rs1, imm(rs2)\nSW rs1, var[index], rs2",
+ "Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes": "Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format": "S-type"
+ },
+ {
+ "Instruction": "BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
+ "Operation": "if (rs1 == rs2) PC = PC + imm",
+ "Notes": "Branch if equal",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "BNE rs1, rs2, imm\nBNE rs1, rs2, label+offset",
+ "Operation": "if (rs1 != rs2) PC = PC + imm",
+ "Notes": "Branch if not equal",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "BLT rs1, rs2, imm\nBLT rs1, rs2, label+offset",
+ "Operation": "if (rs1 =s rs2) PC = PC + imm",
+ "Notes": "Branch if greater than or equal",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "BLTU rs1, rs2, imm\nBLTU rs1, rs2, label+offset",
+ "Operation": "if (rs1 =u rs2) PC = PC + imm",
+ "Notes": "Branch if greater than or equal (unsigned)",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "LUI rd, imm",
+ "Operation": "rd = imm << 12",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "AUIPC rd, imm",
+ "Operation": "rd = PC + (imm << 12)",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "JAL rd, addr\nJAL rd, label+offset",
+ "Operation": "rd = PC + 4; PC = addr",
+ "Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
+ "Format": "J-type"
+ },
+ {
+ "Instruction": "CSRRW rd, csr, rs1",
+ "Operation": "rd = csr; csr = rs1",
+ "Notes": "Atomic read/write",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRS rd, csr, rs1",
+ "Operation": "rd = csr; csr = csr | rs1",
+ "Notes": "Atomic read/set. rs1 serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRC rd, csr, rs1",
+ "Operation": "rd = csr; csr = csr & ~rs1",
+ "Notes": "Atomic read/clear. rs1 serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRWI rd, csr, uimm",
+ "Operation": "rd = csr; csr = uimm",
+ "Notes": "Atomic read/write",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRSI rd, csr, uimm",
+ "Operation": "rd = csr; csr = csr | uimm",
+ "Notes": "Atomic read/set. uimm serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRCI rd, csr, uimm",
+ "Operation": "rd = csr; csr = csr & ~uimm",
+ "Notes": "Atomic read/clear. uimm serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "NOP",
+ "Operation": "-",
+ "Notes": "No operation. Translated to ADDI x0, x0, 0",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LA rd, var[index]",
+ "Operation": "rd = &var[index]",
+ "Notes": "Load variable address into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LI rd, imm",
+ "Operation": "rd = imm",
+ "Notes": "Load 32 bit immediate into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "MV rd, rs",
+ "Operation": "rd = rs",
+ "Notes": "Translated to ADDI rd, rs, 0",
+ "Format": "Pseudo"
+ }
+ ],
+ "other": []
+}
From fcfd9a61df41539faa49a3041d0f34aba64298f3 Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Fri, 26 Apr 2024 12:32:16 +0200
Subject: [PATCH 066/138] split instructions into sections
---
webgui/src/components/riscv/RiscvHelp.vue | 1135 +--------------------
webgui/src/data/riscv_instructions.json | 107 +-
2 files changed, 99 insertions(+), 1143 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index d694144..c7069d8 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -2,7 +2,6 @@
@@ -12,1158 +11,110 @@ const fields = ["Instruction", "Operation", "Notes", "Format"];
This simulator supports a subset of the RISC-V32 ISA. The supported
instructions are listed below.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADD rd, rs1, rs2
-
-
- rd = rs1 + rs2
-
-
-
-
-
- SUB rd, rs1, rs2
-
-
- rd = rs1 - rs2
-
-
-
-
-
- SLL rd, rs1, rs2
-
-
- rd = rs1 << rs2
-
-
-
-
-
- SRL rd, rs1, rs2
-
-
- rd = rs1 >> rs2
-
-
Logical right shift
-
-
-
- SRA rd, rs1, rs2
-
-
- rd = rs1 >>a rs2
-
-
Arithmetic right shift
-
-
-
- SLT rd, rs1, rs2
-
-
- rd = rs1 <s rs2
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in rs2,
- otherwise 0 (both values are treated
- as signed)
-
-
-
-
- SLTU rd, rs1, rs2
-
-
- rd = rs1 <u rs2
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in rs2,
- otherwise 0 (both values are treated
- as unsigned)
-
-
-
-
- AND rd, rs1, rs2
-
-
- rd = rs1 & rs2
-
-
-
-
-
- OR rd, rs1, rs2
-
-
- rd = rs1 | rs2
-
-
-
-
-
- XOR rd, rs1, rs2
-
-
- rd = rs1 ^ rs2
-
-
-
-
-
- MUL rd, rs1, rs2
-
-
- rd = rs1 * rs2
-
-
- (M), places the lower 32 bits of the
- result in the destination register
-
-
-
-
- MULH rd, rs1, rs2
-
-
- rd = rs1 s*s rs2
-
-
- (M), places the upper 32 bits of the
- result in the destination register,
- both rs1 and rs2 are treated as
- signed
-
-
-
-
- MULHU rd, rs1, rs2
-
-
- rd = rs1 u*u rs2
-
-
- (M), places the upper 32 bits of the
- result in the destination register,
- both rs1 and rs2 are treated as
- unsigned
-
-
-
-
- MULHSU rd, rs1, rs2
-
-
- rd = rs1 s*u rs2
-
-
- (M), places the upper 32 bits of the
- result in the destination register,
- rs1 treated as signed, rs2 treated
- as unsigned
-
-
-
-
- DIV rd, rs1, rs2
-
-
- rd = rs1 /s rs2
-
-
(M), signed integer division
-
-
-
- DIVU rd, rs1, rs2
-
-
- rd = rs1 /u rs2
-
-
(M), unsigned integer division
-
-
-
- REM rd, rs1, rs2
-
-
- rd = rs1 %s rs2
-
-
- (M), remainder of signed integer
- division
-
-
-
-
- REMU rd, rs1, rs2
-
-
- rd = rs1 %u rs2
-
-
- (M), remainder of unsigned integer
- division
-
-
-
-
-
-
- Note: Instructions marked with (M) are part of the
- "M" Standard Extension for Integer Multiplication
- and Division.
-
-
-
-
-
-
-
-
-
-
-
- Unless otherwise specified, the immediate
- (imm) has a length of 12 bits and is
- sign extended to 32 bits.
-
- var is a variable name,
- index is an optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADDI rd, rs1, imm
-
-
- rd = rs1 + imm
-
-
-
-
-
- SLTI rd, rs1, imm
-
-
- rd = rs1 <s imm
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in imm,
- otherwise 0 (both values are treated
- as signed)
-
-
-
-
- SLTIU rd, rs1, imm
-
-
- rd = rs1 <u imm
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in imm,
- otherwise 0 (both values are treated
- as unsigned)
-
-
-
-
- ANDI rd, rs1, imm
-
-
- rd = rs1 & imm
-
-
-
-
-
- ORI rd, rs1, imm
-
-
- rd = rs1 | imm
-
-
-
-
-
- XORI rd, rs1, imm
-
-
- rd = rs1 ^ imm
-
-
-
-
-
- SLLI rd, rs1, imm
-
-
- rd = rs1 << imm
-
-
- imm is unsigned, with a
- length of 5 bits
-
-
-
-
- SRLI rd, rs1, imm
-
-
- rd = rs1 >> imm
-
-
- Logical right shift. imm
- is unsigned, with a length of 5 bits
-
-
-
-
- SRAI rd, rs1, imm
-
-
- rd = rs1 >>a imm
-
-
- Arithmetic right shift. imm
- is unsigned, with a length of 5 bits
-
- Jump and link register.
- rd is set to the
- address of the instruction following
- the jump. The jump target is
- rs1 + imm
- with the least significant bit
- cleared.
-
- The immediate (imm) has a length of 20
- bits and is sign extended to 32 bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- LUI rd, imm
-
-
- rd = imm << 12
-
-
-
-
-
- AUIPC rd, imm
-
-
- rd = PC + (imm <<
- 12)
-
-
-
-
-
-
-
-
-
+
-
+
-
- The address to jump to (addr), is
- encoded relative to the current pc in a 21 bit
- immediate that is sign extended to 32 bits and added
- to the current pc.
- Offsets are optional, and in hexadecimal format.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- JAL rd, addr
- JAL rd, label+offset
-
-
- rd = PC + 4; PC = addr
-
-
- Jump and link.
- rd is set to the
- address of the instruction following
- the jump.
-
-
-
-
-
+
-
+
-
- Currently not implemented in 5-stage pipeline
- mode.
-
- The unsigned immediate (uimm) has a
- length of 5 bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- CSRRW rd, csr, rs1
-
-
- rd = csr; csr = rs1
-
-
Atomic read/write
-
-
-
- CSRRS rd, csr, rs1
-
-
- rd = csr; csr = csr | rs1
-
-
- Atomic read/set.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRC rd, csr, rs1
-
-
- rd = csr; csr = csr &
- ~rs1
-
-
- Atomic read/clear.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRWI rd, csr, uimm
-
-
- rd = csr; csr = uimm
-
-
Atomic read/write
-
-
-
- CSRRSI rd, csr, uimm
-
-
- rd = csr; csr = csr |
- uimm
-
-
- Atomic read/set.
- uimm
- serves as a bit mask
-
-
-
-
- CSRRCI rd, csr, uimm
-
-
- rd = csr; csr = csr &
- ~uimm
-
-
- Atomic read/clear.
- uimm
- serves as a bit mask
-
-
-
-
-
+
-
+
-
- var is a variable name,
- index is an optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- NOP
-
-
-
-
- No operation. Translated to
- ADDI x0, x0, 0
-
-
-
-
- LA rd, var[index]
-
-
- rd = &var[index]
-
-
- Load variable address into
- rd
-
-
-
-
- LI rd, imm
-
-
- rd = imm
-
-
- Load 32 bit immediate into
- rd
-
-
-
-
- MV rd, rs
-
-
rd = rs
-
- Translated to
- ADDI rd, rs, 0
-
-
-
-
-
+
-
+
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- EBREAK
-
-
-
-
- Recognized but currently not
- implemented
-
-
-
-
- FENCE rd, rs1
-
-
-
-
- Recognized but currently not
- implemented
-
-
-
-
-
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index ec98eaa..18aafdb 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -1,5 +1,5 @@
{
- "all": [
+ "computational": [
{
"Instruction": "ADD rd, rs1, rs2",
"Operation": "rd = rs1 + rs2",
@@ -162,6 +162,44 @@
"Notes": "Arithmetic right shift. imm is unsigned, with a length of 5 bits",
"Format": "I-type"
},
+ {
+ "Instruction": "LUI rd, imm",
+ "Operation": "rd = imm << 12",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "AUIPC rd, imm",
+ "Operation": "rd = PC + (imm << 12)",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "NOP",
+ "Operation": "-",
+ "Notes": "No operation. Translated to ADDI x0, x0, 0",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LA rd, var[index]",
+ "Operation": "rd = &var[index]",
+ "Notes": "Load variable address into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LI rd, imm",
+ "Operation": "rd = imm",
+ "Notes": "Load 32 bit immediate into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "MV rd, rs",
+ "Operation": "rd = rs",
+ "Notes": "Translated to ADDI rd, rs, 0",
+ "Format": "Pseudo"
+ }
+ ],
+ "memory-accesses": [
{
"Instruction": "LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
"Operation": "rd = M[rs1 + imm] rd = var[index]",
@@ -192,18 +230,6 @@
"Notes": "Load two bytes",
"Format": "I-type"
},
- {
- "Instruction": "JALR rd, rs1, imm",
- "Operation": "rd = PC + 4; PC = rs1 + imm",
- "Notes": "Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
- "Format": "I-type"
- },
- {
- "Instruction": "ECALL",
- "Operation": "environment call",
- "Notes": "See section ECALLs.",
- "Format": "I-type"
- },
{
"Instruction": "SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
"Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
@@ -221,6 +247,14 @@
"Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
"Notes": "Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format": "S-type"
+ }
+ ],
+ "jumps and branches": [
+ {
+ "Instruction": "JALR rd, rs1, imm",
+ "Operation": "rd = PC + 4; PC = rs1 + imm",
+ "Notes": "Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
+ "Format": "I-type"
},
{
"Instruction": "BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
@@ -258,23 +292,19 @@
"Notes": "Branch if greater than or equal (unsigned)",
"Format": "B-type"
},
- {
- "Instruction": "LUI rd, imm",
- "Operation": "rd = imm << 12",
- "Notes": null,
- "Format": "U"
- },
- {
- "Instruction": "AUIPC rd, imm",
- "Operation": "rd = PC + (imm << 12)",
- "Notes": null,
- "Format": "U"
- },
{
"Instruction": "JAL rd, addr\nJAL rd, label+offset",
"Operation": "rd = PC + 4; PC = addr",
"Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
"Format": "J-type"
+ }
+ ],
+ "system instructions": [
+ {
+ "Instruction": "ECALL",
+ "Operation": "environment call",
+ "Notes": "See section ECALLs.",
+ "Format": "I-type"
},
{
"Instruction": "CSRRW rd, csr, rs1",
@@ -311,31 +341,6 @@
"Operation": "rd = csr; csr = csr & ~uimm",
"Notes": "Atomic read/clear. uimm serves as a bit mask",
"Format": "CSR"
- },
- {
- "Instruction": "NOP",
- "Operation": "-",
- "Notes": "No operation. Translated to ADDI x0, x0, 0",
- "Format": "Pseudo"
- },
- {
- "Instruction": "LA rd, var[index]",
- "Operation": "rd = &var[index]",
- "Notes": "Load variable address into rd",
- "Format": "Pseudo"
- },
- {
- "Instruction": "LI rd, imm",
- "Operation": "rd = imm",
- "Notes": "Load 32 bit immediate into rd",
- "Format": "Pseudo"
- },
- {
- "Instruction": "MV rd, rs",
- "Operation": "rd = rs",
- "Notes": "Translated to ADDI rd, rs, 0",
- "Format": "Pseudo"
}
- ],
- "other": []
+ ]
}
From a542e1efa10267d5446249c1da8944017913912b Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Fri, 26 Apr 2024 15:29:58 +0200
Subject: [PATCH 067/138] reordering and adding notes back
---
webgui/src/components/riscv/RiscvHelp.vue | 47 +++++++++++++++++++++++
webgui/src/data/riscv_instructions.json | 24 ++++++------
2 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index c7069d8..876a274 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -34,6 +34,20 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
+
+ Notes:
+ - Instructions marked with (M) are part of the "M”
+ Standard Extension for Integer Multiplication and
+ Division.
+
+ - Unless otherwise specified, the immediate
+ (imm) of I-type instructions has a
+ length of 12 bits and is sign extended to 32 bits.
+
+ - The immediate (imm) of U-Type
+ instructions has a length of 20 bits and is sign
+ extended to 32 bits.
+
+ Notes:
+ - The immediate (imm) of the instructions in this
+ paragraph has a length of 12 bits and is sign
+ extended to 32 bits.
+
+ - var is a variable name,
+ index is an optional array index.
+
@@ -88,6 +111,20 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
riscv_instructions['jumps and branches']
"
/>
+
+ Notes:
+ - JAL instructions encode the address to jump to
+ (addr), relative to the current pc in a
+ 21 bit immediate that is sign extended to 32 bits
+ and added to the current pc.
+ - The JALR immediate (imm) has a length
+ of 12 bits and is sign extended to 32 bits.
+ - The immediate (imm ) of B-type
+ instructions has a length of 13 bits and is sign
+ extended to 32 bits.
+ - offset is optional, and in
+ hexadecimal format.
+
+ Notes:
+ -
+ CSR Currently not implemented in 5-stage
+ pipeline mode.
+ - The unsigned immediate (uimm) has a
+ length of 5 bits.
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index 18aafdb..5fe05a4 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -180,12 +180,6 @@
"Notes": "No operation. Translated to ADDI x0, x0, 0",
"Format": "Pseudo"
},
- {
- "Instruction": "LA rd, var[index]",
- "Operation": "rd = &var[index]",
- "Notes": "Load variable address into rd",
- "Format": "Pseudo"
- },
{
"Instruction": "LI rd, imm",
"Operation": "rd = imm",
@@ -247,9 +241,21 @@
"Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
"Notes": "Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format": "S-type"
+ },
+ {
+ "Instruction": "LA rd, var[index]",
+ "Operation": "rd = &var[index]",
+ "Notes": "Load variable address into rd",
+ "Format": "Pseudo"
}
],
"jumps and branches": [
+ {
+ "Instruction": "JAL rd, addr\nJAL rd, label+offset",
+ "Operation": "rd = PC + 4; PC = addr",
+ "Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
+ "Format": "J-type"
+ },
{
"Instruction": "JALR rd, rs1, imm",
"Operation": "rd = PC + 4; PC = rs1 + imm",
@@ -291,12 +297,6 @@
"Operation": "if (rs1 >=u rs2) PC = PC + imm",
"Notes": "Branch if greater than or equal (unsigned)",
"Format": "B-type"
- },
- {
- "Instruction": "JAL rd, addr\nJAL rd, label+offset",
- "Operation": "rd = PC + 4; PC = addr",
- "Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
- "Format": "J-type"
}
],
"system instructions": [
From c58a940e6ae6fded89606bf2423ea5d381a8f3c6 Mon Sep 17 00:00:00 2001
From: Michael Kuhn
Date: Fri, 26 Apr 2024 15:44:45 +0200
Subject: [PATCH 068/138] update text
---
webgui/src/components/riscv/RiscvHelp.vue | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index 876a274..1a2e0d0 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -8,8 +8,8 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
RISC-V
Instructions
- This simulator supports a subset of the RISC-V32 ISA. The supported
- instructions are listed below.
+ This simulator supports a subset of the RISC-V RV32IM ISA. The
+ supported instructions are listed below.
- Notes:
- - Instructions marked with (M) are part of the "M”
- Standard Extension for Integer Multiplication and
- Division.
-
- - Unless otherwise specified, the immediate
- (imm) of I-type instructions has a
- length of 12 bits and is sign extended to 32 bits.
-
- - The immediate (imm) of U-Type
- instructions has a length of 20 bits and is sign
- extended to 32 bits.
-
+
Notes:
+
+
+ Instructions marked with (M) are part of the "M”
+ Standard Extension for Integer Multiplication
+ and Division.
+
+
+ Unless otherwise specified, the immediate
+ (imm) of I-type instructions has a
+ length of 12 bits and is sign extended to 32
+ bits.
+
+
+ The immediate (imm) of U-Type
+ instructions has a length of 20 bits and is sign
+ extended to 32 bits.
+
- Notes:
- - The immediate (imm) of the instructions in this
- paragraph has a length of 12 bits and is sign
- extended to 32 bits.
-
- - var is a variable name,
- index is an optional array index.
-
+
Notes:
+
+
+ The immediate (imm) of the instructions in this
+ paragraph has a length of 12 bits and is sign
+ extended to 32 bits.
+
+
+ var is a variable name,
+ index is an optional array index.
+
+
@@ -111,20 +119,29 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
riscv_instructions['jumps and branches']
"
/>
-
- Notes:
- - JAL instructions encode the address to jump to
- (addr), relative to the current pc in a
- 21 bit immediate that is sign extended to 32 bits
- and added to the current pc.
- - The JALR immediate (imm) has a length
- of 12 bits and is sign extended to 32 bits.
- - The immediate (imm ) of B-type
- instructions has a length of 13 bits and is sign
- extended to 32 bits.
- - offset is optional, and in
- hexadecimal format.
-
+
Notes:
+
+
+ JAL instructions encode the address to jump to
+ (addr), relative to the current pc
+ in a 21 bit immediate that is sign extended to
+ 32 bits and added to the current pc.
+
+
+ The JALR immediate (imm) has a
+ length of 12 bits and is sign extended to 32
+ bits.
+
+
+ The immediate (imm ) of B-type
+ instructions has a length of 13 bits and is sign
+ extended to 32 bits.
+
+
+ offset is optional, and in
+ hexadecimal format.
+
- Notes:
- -
- CSR Currently not implemented in 5-stage
- pipeline mode.
- - The unsigned immediate (uimm) has a
- length of 5 bits.
-
+
Notes:
+
+
+ CSR Currently not implemented in 5-stage
+ pipeline mode.
+
+
+ The unsigned immediate (uimm) has a
+ length of 5 bits.
+
+
From 935321cc4ebeaa3a2b23d5433df3713b6c6af8cd Mon Sep 17 00:00:00 2001
From: Michael Kuhn
Date: Wed, 24 Apr 2024 12:29:46 +0200
Subject: [PATCH 070/138] update version string
---
pyproject.toml | 2 +-
webgui/src/main.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 8457cf6..6b799e5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "architecture-simulator"
-version = "1.3.0"
+version = "1.3.1.dev0"
readme = "README.md"
requires-python = ">=3.10"
dependencies = ["pyparsing","fixedint","prompt-toolkit"]
diff --git a/webgui/src/main.js b/webgui/src/main.js
index b98e481..a9e9ffa 100644
--- a/webgui/src/main.js
+++ b/webgui/src/main.js
@@ -1,7 +1,7 @@
import "./scss/styles.scss";
import "./css/main.css";
import "./css/splitjs.css";
-import architectureSimulatorPackageUrl from "../../dist/architecture_simulator-1.3.0-py3-none-any.whl";
+import architectureSimulatorPackageUrl from "../../dist/architecture_simulator-1.3.1.dev0-py3-none-any.whl";
import { createApp } from "vue";
From a52d73a36ee63efc6d15cc35c30ea5640ba99d13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 09:32:39 +0200
Subject: [PATCH 071/138] Added a test for the bug
---
tests/test_riscv_pipeline.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tests/test_riscv_pipeline.py b/tests/test_riscv_pipeline.py
index 881a5b1..39215b5 100644
--- a/tests/test_riscv_pipeline.py
+++ b/tests/test_riscv_pipeline.py
@@ -1418,3 +1418,19 @@ def test_stall_2(self):
self.assertEqual(sim.state.performance_metrics.cycles, 14)
self.assertEqual(sim.state.performance_metrics.stalls, 2)
self.assertEqual(sim.state.performance_metrics.flushes, 0)
+
+ def test_exit(self):
+ program = """li a7, 10
+ ecall
+ nop
+ nop
+ nop
+ nop
+ nop"""
+
+ sim = RiscvSimulation(mode="five_stage_pipeline")
+
+ sim.load_program(program)
+ sim.run()
+ self.assertEqual(sim.state.performance_metrics.cycles, 8)
+ self.assertEqual(sim.state.performance_metrics.instruction_count, 2)
From 065536196f6b6dcc0dafcfa572454fffdcc53160 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 10:15:57 +0200
Subject: [PATCH 072/138] Ecall now continues until the wb stage But it doesn't
flush yet, which is not good
---
.../isa/riscv/rv32i_instructions.py | 42 +++++++++++++------
.../uarch/riscv/pipeline_registers.py | 2 +
architecture_simulator/uarch/riscv/stages.py | 28 +++++++++----
3 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/architecture_simulator/isa/riscv/rv32i_instructions.py b/architecture_simulator/isa/riscv/rv32i_instructions.py
index fdb224f..2c925a8 100644
--- a/architecture_simulator/isa/riscv/rv32i_instructions.py
+++ b/architecture_simulator/isa/riscv/rv32i_instructions.py
@@ -825,38 +825,56 @@ def behavior(
self, architectural_state: RiscvArchitecturalState
) -> RiscvArchitecturalState:
"""RaiseException(EnvironmentCall)"""
+ result = self.process_ecall(architectural_state)
+ if type(result) is int:
+ architectural_state.exit_code = result
+ elif type(result) is str:
+ architectural_state.output += result
+ return architectural_state
+
+ def process_ecall(self, architectural_state: RiscvArchitecturalState) -> str | int:
+ """Processes this ecall. Returns the action to be applied to the architectural state.
+
+ Args:
+ architectural_state (RiscvArchitecturalState): The state on which the ecall shall be applied.
+
+ Raises:
+ ValueError: Raises an error if the ECALL code is invalid.
+
+ Returns:
+ str|int: Returns either a string to be printed to the output or an exit code.
+ """
code = int(architectural_state.register_file.registers[17])
arg = int(architectural_state.register_file.registers[10])
match code:
case 1: # print arg as sint
- architectural_state.output += str(fixedint.Int32(arg))
+ return str(fixedint.Int32(arg))
case 2: # print arg as 32-bit float
- architectural_state.output += str(
- unpack(">f", arg.to_bytes(4, "big"))[0]
- )
+ return str(unpack(">f", arg.to_bytes(4, "big"))[0])
case 4: # print null-terminated string stored at address in arg
address = arg
+ result = ""
while (
byte := architectural_state.memory.read_byte(address, False)
) != 0:
- architectural_state.output += chr(byte % 128)
+ result += chr(byte % 128)
address += 1
+ return result
case 11: # print arg as ascii char
- architectural_state.output += chr(arg % 128)
+ return chr(arg % 128)
case 34: # print arg as hex
- architectural_state.output += "0x" + "{:X}".format(arg)
+ return "0x" + "{:X}".format(arg)
case 35: # print arg as bin
- architectural_state.output += bin(arg)
+ return bin(arg)
case 36: # print arg as uint
- architectural_state.output += str(arg)
+ return str(arg)
case 10: # exit with status 0
- architectural_state.exit_code = 0
+ return 0
case 93: # exit with arg as status
- architectural_state.exit_code = arg
+ return arg
case _:
raise ValueError(f"{code} (register a7) is not a valid code for ECALL")
- return architectural_state
def alu_compute(
self, alu_in_1: int | None, alu_in_2: int | None
diff --git a/architecture_simulator/uarch/riscv/pipeline_registers.py b/architecture_simulator/uarch/riscv/pipeline_registers.py
index 71dd00e..1f49d7d 100644
--- a/architecture_simulator/uarch/riscv/pipeline_registers.py
+++ b/architecture_simulator/uarch/riscv/pipeline_registers.py
@@ -63,6 +63,7 @@ class ExecutePipelineRegister(PipelineRegister):
pc_plus_imm: Optional[int] = None
branch_prediction: Optional[bool] = None
pc_plus_instruction_length: Optional[int] = None
+ exit_code: Optional[int] = None
abbreviation = "EX"
@@ -80,6 +81,7 @@ class MemoryAccessPipelineRegister(PipelineRegister):
pc_plus_imm: Optional[int] = None
pc_plus_instruction_length: Optional[int] = None
imm: Optional[int] = None
+ exit_code: Optional[int] = None
abbreviation = "MEM"
diff --git a/architecture_simulator/uarch/riscv/stages.py b/architecture_simulator/uarch/riscv/stages.py
index 2d724f6..f1944ad 100644
--- a/architecture_simulator/uarch/riscv/stages.py
+++ b/architecture_simulator/uarch/riscv/stages.py
@@ -237,6 +237,7 @@ def behavior(
# ECALL needs some special behavior (flush and print to output)
stall_signal = None
+ exit_code = None
if isinstance(pipeline_register.instruction, ECALL):
# assume that all further stages need to be empty, unless this stage is already stalled and the value of the next register is only for display purposes
for other_pr in pipeline_registers[
@@ -249,7 +250,11 @@ def behavior(
stall_signal = StallSignal(2)
break
if stall_signal is None:
- pipeline_register.instruction.behavior(state)
+ ecall_result = pipeline_register.instruction.process_ecall(state)
+ if type(ecall_result) is str:
+ state.output += ecall_result
+ elif type(ecall_result) is int:
+ exit_code = ecall_result
return ExecutePipelineRegister(
stall_signal=stall_signal,
@@ -267,6 +272,7 @@ def behavior(
branch_prediction=pipeline_register.branch_prediction,
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
address_of_instruction=pipeline_register.address_of_instruction,
+ exit_code=exit_code,
)
@@ -349,6 +355,7 @@ def behavior(
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
imm=pipeline_register.imm,
address_of_instruction=pipeline_register.address_of_instruction,
+ exit_code=pipeline_register.exit_code,
)
@@ -402,6 +409,9 @@ def behavior(
architectural_state=state,
)
+ if pipeline_register.exit_code is not None:
+ state.exit_code = pipeline_register.exit_code
+
return RegisterWritebackPipelineRegister(
instruction=pipeline_register.instruction,
register_write_data=register_write_data,
@@ -504,12 +514,16 @@ def behavior(
result_pr.pc_plus_imm = state.program_counter + result_pr.imm
a_comparison, a_result = result_pr.instruction.alu_compute(
- state.program_counter
- if result_pr.control_unit_signals.alu_src_1
- else result_pr.register_read_data_1,
- result_pr.imm
- if result_pr.control_unit_signals.alu_src_2
- else result_pr.register_read_data_2,
+ (
+ state.program_counter
+ if result_pr.control_unit_signals.alu_src_1
+ else result_pr.register_read_data_1
+ ),
+ (
+ result_pr.imm
+ if result_pr.control_unit_signals.alu_src_2
+ else result_pr.register_read_data_2
+ ),
)
result_pr.alu_comparison = bool(a_comparison)
From f5c0df52e2a2feb19239b97c92e951407ff28c1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 10:19:09 +0200
Subject: [PATCH 073/138] Added a test for flushing
---
tests/test_riscv_pipeline.py | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/tests/test_riscv_pipeline.py b/tests/test_riscv_pipeline.py
index 39215b5..d3412b2 100644
--- a/tests/test_riscv_pipeline.py
+++ b/tests/test_riscv_pipeline.py
@@ -1419,7 +1419,7 @@ def test_stall_2(self):
self.assertEqual(sim.state.performance_metrics.stalls, 2)
self.assertEqual(sim.state.performance_metrics.flushes, 0)
- def test_exit(self):
+ def test_exit_1(self):
program = """li a7, 10
ecall
nop
@@ -1434,3 +1434,19 @@ def test_exit(self):
sim.run()
self.assertEqual(sim.state.performance_metrics.cycles, 8)
self.assertEqual(sim.state.performance_metrics.instruction_count, 2)
+
+ def test_exit_2(self):
+ # make sure instructions are flushed to prevent unwanted "side effects"
+ program = """li x3, 555
+li a7, 10
+ecall
+sw x3, -4(x0)
+nop
+nop"""
+ sim = RiscvSimulation(mode="five_stage_pipeline")
+
+ sim.load_program(program)
+ sim.run()
+ self.assertEqual(sim.state.performance_metrics.cycles, 9)
+ self.assertEqual(sim.state.performance_metrics.instruction_count, 3)
+ self.assertEqual(sim.state.memory.read_word(-4, False), 0)
From f1a07081c6442de8dbc9d0a8ad962a7f2f9cc74a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Richard=20M=C3=BCller?=
Date: Fri, 26 Apr 2024 10:53:44 +0200
Subject: [PATCH 074/138] Added flushes for ecall exit
---
architecture_simulator/uarch/riscv/stages.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/architecture_simulator/uarch/riscv/stages.py b/architecture_simulator/uarch/riscv/stages.py
index f1944ad..023de5a 100644
--- a/architecture_simulator/uarch/riscv/stages.py
+++ b/architecture_simulator/uarch/riscv/stages.py
@@ -238,6 +238,7 @@ def behavior(
# ECALL needs some special behavior (flush and print to output)
stall_signal = None
exit_code = None
+ flush_signal = None # Needed for exiting the simulation (ecall 10/93)
if isinstance(pipeline_register.instruction, ECALL):
# assume that all further stages need to be empty, unless this stage is already stalled and the value of the next register is only for display purposes
for other_pr in pipeline_registers[
@@ -255,6 +256,10 @@ def behavior(
state.output += ecall_result
elif type(ecall_result) is int:
exit_code = ecall_result
+ assert pipeline_register.pc_plus_instruction_length is not None
+ flush_signal = FlushSignal(
+ False, pipeline_register.pc_plus_instruction_length
+ )
return ExecutePipelineRegister(
stall_signal=stall_signal,
@@ -273,6 +278,7 @@ def behavior(
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
address_of_instruction=pipeline_register.address_of_instruction,
exit_code=exit_code,
+ flush_signal=flush_signal,
)
@@ -331,6 +337,12 @@ def behavior(
flush_signal = FlushSignal(
inclusive=False, address=pipeline_register.result
)
+ elif pipeline_register.exit_code is not None:
+ # Exit codes stem from ecalls which cannot cause branches and thus cannot generate other flush signals
+ assert pipeline_register.pc_plus_instruction_length is not None
+ flush_signal = FlushSignal(
+ False, pipeline_register.pc_plus_instruction_length
+ )
else:
flush_signal = None
@@ -409,7 +421,12 @@ def behavior(
architectural_state=state,
)
+ flush_signal = None
if pipeline_register.exit_code is not None:
+ assert pipeline_register.pc_plus_instruction_length is not None
+ flush_signal = FlushSignal(
+ False, pipeline_register.pc_plus_instruction_length
+ )
state.exit_code = pipeline_register.exit_code
return RegisterWritebackPipelineRegister(
@@ -422,6 +439,7 @@ def behavior(
pc_plus_instruction_length=pipeline_register.pc_plus_instruction_length,
imm=pipeline_register.imm,
address_of_instruction=pipeline_register.address_of_instruction,
+ flush_signal=flush_signal,
)
From 07abd72e62ad4c01d133a7017c2f77b04ce7d390 Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Thu, 25 Apr 2024 17:05:58 +0200
Subject: [PATCH 075/138] begin implementing accordion for riscv help page
---
webgui/src/components/riscv/RiscvHelp.vue | 1561 ++++++++++++---------
1 file changed, 879 insertions(+), 682 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index c1ba06d..d05c360 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -7,694 +7,891 @@
This simulator supports a subset of the RISC-V32 ISA. The supported
instructions are listed below.
-
R-Type
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADD rd, rs1, rs2
-
-
- rd = rs1 + rs2
-
-
-
-
-
- SUB rd, rs1, rs2
-
-
- rd = rs1 - rs2
-
-
-
-
-
- SLL rd, rs1, rs2
-
-
- rd = rs1 << rs2
-
-
-
-
-
- SRL rd, rs1, rs2
-
-
- rd = rs1 >> rs2
-
-
Logical right shift
-
-
-
- SRA rd, rs1, rs2
-
-
- rd = rs1 >>a rs2
-
-
Arithmetic right shift
-
-
-
- SLT rd, rs1, rs2
-
-
- rd = rs1 <s rs2
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- rs2, otherwise 0 (both values are
- treated as signed)
-
-
-
-
- SLTU rd, rs1, rs2
-
-
- rd = rs1 <u rs2
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- rs2, otherwise 0 (both values are
- treated as unsigned)
-
-
-
-
- AND rd, rs1, rs2
-
-
- rd = rs1 & rs2
-
-
-
-
-
- OR rd, rs1, rs2
-
-
- rd = rs1 | rs2
-
-
-
-
-
- XOR rd, rs1, rs2
-
-
- rd = rs1 ^ rs2
-
-
-
-
-
- MUL rd, rs1, rs2
-
-
- rd = rs1 * rs2
-
-
- (M), places the lower 32 bits of the result in the
- destination register
-
-
-
-
- MULH rd, rs1, rs2
-
-
- rd = rs1 s*s rs2
-
-
- (M), places the upper 32 bits of the result in the
- destination register, both rs1 and rs2 are treated
- as signed
-
-
-
-
- MULHU rd, rs1, rs2
-
-
- rd = rs1 u*u rs2
-
-
- (M), places the upper 32 bits of the result in the
- destination register, both rs1 and rs2 are treated
- as unsigned
-
-
-
-
- MULHSU rd, rs1, rs2
-
-
- rd = rs1 s*u rs2
-
-
- (M), places the upper 32 bits of the result in the
- destination register, rs1 treated as signed, rs2
- treated as unsigned
-
-
-
-
- DIV rd, rs1, rs2
-
-
- rd = rs1 /s rs2
-
-
(M), signed integer division
-
-
-
- DIVU rd, rs1, rs2
-
-
- rd = rs1 /u rs2
-
-
(M), unsigned integer division
-
-
-
- REM rd, rs1, rs2
-
-
- rd = rs1 %s rs2
-
-
(M), remainder of signed integer division
-
-
-
- REMU rd, rs1, rs2
-
-
- rd = rs1 %u rs2
-
-
(M), remainder of unsigned integer division
-
-
-
-
-
- Note: Instructions marked with (M) are part of the "M” Standard
- Extension for Integer Multiplication and Division.
-
-
-
I-Type
-
- Unless otherwise specified, the immediate (imm) has a
- length of 12 bits and is sign extended to 32 bits.
-
- var is a variable name, index is an
- optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADDI rd, rs1, imm
-
-
- rd = rs1 + imm
-
-
-
-
-
- SLTI rd, rs1, imm
-
-
- rd = rs1 <s imm
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- imm, otherwise 0 (both values are
- treated as signed)
-
-
-
-
- SLTIU rd, rs1, imm
-
-
- rd = rs1 <u imm
-
-
- Set rd to 1 if the value in
- rs1 is less than the value in
- imm, otherwise 0 (both values are
- treated as unsigned)
-
-
-
-
- ANDI rd, rs1, imm
-
-
- rd = rs1 & imm
-
-
-
-
-
- ORI rd, rs1, imm
-
-
- rd = rs1 | imm
-
-
-
-
-
- XORI rd, rs1, imm
-
-
- rd = rs1 ^ imm
-
-
-
-
-
- SLLI rd, rs1, imm
-
-
- rd = rs1 << imm
-
-
- imm is unsigned, with a length of 5
- bits
-
-
-
-
- SRLI rd, rs1, imm
-
-
- rd = rs1 >> imm
-
-
- Logical right shift. imm
- is unsigned, with a length of 5 bits
-
-
-
-
- SRAI rd, rs1, imm
-
-
- rd = rs1 >>a imm
-
-
- Arithmetic right shift. imm
- is unsigned, with a length of 5 bits
-
- Jump and link register.
- rd is set to the address of the
- instruction following the jump. The jump target is
- rs1 + imm
- with the least significant bit cleared.
-
+ Set rd to 1 if the
+ value in rs1 is less
+ than the value in rs2,
+ otherwise 0 (both values are treated
+ as signed)
+
+
+
+
+ SLTU rd, rs1, rs2
+
+
+ rd = rs1 <u rs2
+
+
+ Set rd to 1 if the
+ value in rs1 is less
+ than the value in rs2,
+ otherwise 0 (both values are treated
+ as unsigned)
+
+
+
+
+ AND rd, rs1, rs2
+
+
+ rd = rs1 & rs2
+
+
+
+
+
+ OR rd, rs1, rs2
+
+
+ rd = rs1 | rs2
+
+
+
+
+
+ XOR rd, rs1, rs2
+
+
+ rd = rs1 ^ rs2
+
+
+
+
+
+ MUL rd, rs1, rs2
+
+
+ rd = rs1 * rs2
+
+
+ (M), places the lower 32 bits of the
+ result in the destination register
+
+
+
+
+ MULH rd, rs1, rs2
+
+
+ rd = rs1 s*s rs2
+
+
+ (M), places the upper 32 bits of the
+ result in the destination register,
+ both rs1 and rs2 are treated as
+ signed
+
+
+
+
+ MULHU rd, rs1, rs2
+
+
+ rd = rs1 u*u rs2
+
+
+ (M), places the upper 32 bits of the
+ result in the destination register,
+ both rs1 and rs2 are treated as
+ unsigned
+
+
+
+
+ MULHSU rd, rs1, rs2
+
+
+ rd = rs1 s*u rs2
+
+
+ (M), places the upper 32 bits of the
+ result in the destination register,
+ rs1 treated as signed, rs2 treated
+ as unsigned
+
+
+
+
+ DIV rd, rs1, rs2
+
+
+ rd = rs1 /s rs2
+
+
(M), signed integer division
+
+
+
+ DIVU rd, rs1, rs2
+
+
+ rd = rs1 /u rs2
+
+
(M), unsigned integer division
+
+
+
+ REM rd, rs1, rs2
+
+
+ rd = rs1 %s rs2
+
+
+ (M), remainder of signed integer
+ division
+
+
+
+
+ REMU rd, rs1, rs2
+
+
+ rd = rs1 %u rs2
+
+
+ (M), remainder of unsigned integer
+ division
+
+
+
+
+
+
+ Note: Instructions marked with (M) are part of the
+ "M" Standard Extension for Integer Multiplication
+ and Division.
+
+
+
+
+
+
+
+
+
+
+
+ Unless otherwise specified, the immediate
+ (imm) has a length of 12 bits and is
+ sign extended to 32 bits.
+
+ var is a variable name,
+ index is an optional array index.
+
+ Jump and link register.
+ rd is set to the
+ address of the instruction following
+ the jump. The jump target is
+ rs1 + imm
+ with the least significant bit
+ cleared.
+
+ The immediate (imm) has a length of 20
+ bits and is sign extended to 32 bits.
+
+
+
-
-
- if (rs1 >=u rs2) PC = PC + imm
-
-
Branch if greater than or equal (unsigned)
-
-
-
-
-
-
U-Type
-
- The immediate (imm) has a length of 20 bits and is sign
- extended to 32 bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- LUI rd, imm
-
-
- rd = imm << 12
-
-
-
-
-
- AUIPC rd, imm
-
-
- rd = PC + (imm << 12)
-
-
-
-
-
-
-
-
J-Type
-
- The address to jump to (addr), is encoded relative to
- the current pc in a 21 bit immediate that is sign extended to 32
- bits and added to the current pc.
- Offsets are optional, and in hexadecimal format.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- JAL rd, addr
- JAL rd, label+offset
+
+
Instruction
+
Operation
+
Notes
+
+
+
+
+
+ LUI rd, imm
+
+
+ rd = imm << 12
+
+
+
+
+
+ AUIPC rd, imm
+
+
+ rd = PC + (imm <<
+ 12)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The address to jump to (addr), is
+ encoded relative to the current pc in a 21 bit
+ immediate that is sign extended to 32 bits and added
+ to the current pc.
+ Offsets are optional, and in hexadecimal format.
+
+
+
-
-
- rd = PC + 4; PC = addr
-
-
- Jump and link.
- rd is set to the address of the
- instruction following the jump.
-
-
-
-
-
+
+
+
Instruction
+
Operation
+
Notes
+
+
+
+
+
+ JAL rd, addr
+ JAL rd, label+offset
+
+
+ rd = PC + 4; PC = addr
+
+
+ Jump and link.
+ rd is set to the
+ address of the instruction following
+ the jump.
+
+
+
+
+
+
+
+
+
CSR-Type
Currently not implemented in 5-stage pipeline mode.
From 4affa4d785624d6cdf5fb6e64b5145838e646e4a Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Thu, 25 Apr 2024 17:36:22 +0200
Subject: [PATCH 076/138] more collapsibles
---
webgui/src/components/riscv/RiscvHelp.vue | 447 +++++++++++++---------
1 file changed, 267 insertions(+), 180 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index d05c360..e35a4bc 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -891,190 +891,277 @@
-
-
CSR-Type
-
- Currently not implemented in 5-stage pipeline mode.
-
- The unsigned immediate (uimm) has a length of 5
- bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- CSRRW rd, csr, rs1
-
-
- rd = csr; csr = rs1
-
-
Atomic read/write
-
-
-
- CSRRS rd, csr, rs1
-
-
- rd = csr; csr = csr | rs1
-
-
- Atomic read/set.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRC rd, csr, rs1
-
-
- rd = csr; csr = csr & ~rs1
-
-
- Atomic read/clear.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRWI rd, csr, uimm
-
-
- rd = csr; csr = uimm
-
-
Atomic read/write
-
-
-
- CSRRSI rd, csr, uimm
-
-
- rd = csr; csr = csr | uimm
-
-
- Atomic read/set.
- uimm
- serves as a bit mask
-
-
-
-
- CSRRCI rd, csr, uimm
-
-
- rd = csr; csr = csr & ~uimm
-
-
- Atomic read/clear.
- uimm
- serves as a bit mask
-
-
-
-
+
+
+
+
+
+
+
+ Currently not implemented in 5-stage pipeline
+ mode.
+
+ The unsigned immediate (uimm) has a
+ length of 5 bits.
+
+
+
+
+
+
Instruction
+
Operation
+
Notes
+
+
+
+
+
+ CSRRW rd, csr, rs1
+
+
+ rd = csr; csr = rs1
+
+
Atomic read/write
+
+
+
+ CSRRS rd, csr, rs1
+
+
+ rd = csr; csr = csr | rs1
+
+
+ Atomic read/set.
+ rs1
+ serves as a bit mask
+
+
+
+
+ CSRRC rd, csr, rs1
+
+
+ rd = csr; csr = csr &
+ ~rs1
+
+
+ Atomic read/clear.
+ rs1
+ serves as a bit mask
+
+
+
+
+ CSRRWI rd, csr, uimm
+
+
+ rd = csr; csr = uimm
+
+
Atomic read/write
+
+
+
+ CSRRSI rd, csr, uimm
+
+
+ rd = csr; csr = csr |
+ uimm
+
+
+ Atomic read/set.
+ uimm
+ serves as a bit mask
+
+
+
+
+ CSRRCI rd, csr, uimm
+
+
+ rd = csr; csr = csr &
+ ~uimm
+
+
+ Atomic read/clear.
+ uimm
+ serves as a bit mask
+
+
+
+
+
+
+
-
-
Pseudoinstructions
-
- var is a variable name, index is an
- optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- NOP
-
-
-
-
- No operation. Translated to
- ADDI x0, x0, 0
-
-
-
-
- LA rd, var[index]
-
-
- rd = &var[index]
-
-
- Load variable address into
- rd
-
-
-
-
- LI rd, imm
-
-
- rd = imm
-
-
- Load 32 bit immediate into
- rd
-
-
-
-
- MV rd, rs
-
-
rd = rs
-
- Translated to
- ADDI rd, rs, 0
-
-
-
-
+
+
+
+
+
+
+
+ var is a variable name,
+ index is an optional array index.
+
- Comments can be added to the code using
- #.
- Labels are added by appending a colon
- : to a label name. They can be used as jump targets.
-
-
+
Other
+
+
+
+
+
+
+
+
+
+ Comments can be added to the code using
+ #.
+ Labels are added by appending a colon
+ : to a label name. They can be used as
+ jump targets.
+
+
# This is a comment
my_label:
addi x1, x1, 1
jal x2, my_label
addi x3, x3, 1 # This line is never reached
-
-
Segments and variables
-
- In addition to the program code, the simulator supports a data
- segment. It can be used to store variables and arrays in the
- simulator's memory.
-
-
- In order to define a data segment, the
- .data directive is used, while the
- .text directive designates the code segment.
-
-
- The following example demonstrates how to declare and use variables
- and arrays, employing all currently supported data types. Note that
- all variables/arrays are word-aligned (addresses are multiples of
- 4), which is achieved by zero-padding preceding variables.
-
-
+ >
+
+
+
+
+
+
+
+
+
+
+ In addition to the program code, the simulator
+ supports a data segment. It can be used to store
+ variables and arrays in the simulator's memory.
+
+
+ In order to define a data segment, the
+ .data directive is used, while the
+ .text directive designates the code
+ segment.
+
+
+ The following example demonstrates how to declare
+ and use variables and arrays, employing all
+ currently supported data types. Note that all
+ variables/arrays are word-aligned (addresses are
+ multiples of 4), which is achieved by zero-padding
+ preceding variables.
+
+
.data
empty_array: .zero 64 # reserves space for 64 words (256 bytes)
# The following two declarations of 'my_var1' are equivalent,
@@ -1212,146 +1256,228 @@ addi x3, x3, 1 # This line is never reached
-
- If no directives are given, the entire input is interpreted as
- code.
- Similarly, if a .data but no
- .text directive is given, every line before the data
- segment is interpreted as code.
-
- There is no fixed segmentation order. However, declaring multiple
- segments of the same type will throw an error.
-
-
-
Cache Simulation
-
- You can activate separate caches for data and instructions in the
- settings. These caches can be configured as Write-through with Write
- no-allocate or Write-back with Write allocate. The number of sets,
- block size and associativity are also configurable. You can also
- choose between LRU and PLRU for the replacement strategy.
-
-
- As the name implies, LRU (Least Recently Used) will always replace
- the block that was used least recently. The LRU value in the cache
- table shows the age of each block. Higher values indicate more
- recently used blocks.
-
-
- PLRU (Pseudo LRU) is an approximation of LRU which is easier to
- implement in hardware. It uses a binary tree with the blocks at its
- leaf nodes. On each non-leaf node is a single bit - a 0 indicates
- that older blocks are in the upper child tree while a 1 indicates
- that older blocks are in the lower child tree.
- When replacing a block, PLRU will choose the one which is oldest
- according to those bits. Then all bits along the path are flipped to
- mark it as the most recent.
- When accessing any block that is stored in the cache, PLRU will
- update all bits along the path to the new block so they correctly
- identify it as the newest block.
- Note that when using PLRU, associativity must be a power of 2 since
- PLRU uses a binary tree in its state.
-
-
- You can also get a visualization of the cache by selecting it in the
- drop down menu in the control bar. Note that for performance
- reasons, this option becomes unavailabe if the cache gets too big.
- Even with the visualization disabled, you should not make the cache
- too big since the site may become unresponsive.
-
-
- When using a data cache, misaligned access to the memory is not
- allowed because it would be unclear what exactly should happen in
- the cache. For example, the following piece of code would not work
- since the accessed value crosses a word boundary:
-
-
lw x1, -5(x0)
-
-
ECALLs
-
- Environment calls (ECALLs) can be used for interacting with the
- environment - currently, ECALLs can be used for printing to the
- console or stopping the simulation. Each ECALL has a different code
- which must be loaded into register a7. Some ECALLs also
- require an argument which must be loaded into register
- a0. The supported ECALLs are identical to those of
- Ripes.
-
+ >
+
+ If no directives are given, the entire input is
+ interpreted as code.
+ Similarly, if a .data but no
+ .text directive is given, every line
+ before the data segment is interpreted as code.
+
+ There is no fixed segmentation order. However,
+ declaring multiple segments of the same type will
+ throw an error.
+
+
+
+
+
+
+
+
+
+
+
+ You can activate separate caches for data and
+ instructions in the settings. These caches can be
+ configured as Write-through with Write no-allocate
+ or Write-back with Write allocate. The number of
+ sets, block size and associativity are also
+ configurable. You can also choose between LRU and
+ PLRU for the replacement strategy.
+
+
+ As the name implies, LRU (Least Recently Used) will
+ always replace the block that was used least
+ recently. The LRU value in the cache table shows the
+ age of each block. Higher values indicate more
+ recently used blocks.
+
+
+ PLRU (Pseudo LRU) is an approximation of LRU which
+ is easier to implement in hardware. It uses a binary
+ tree with the blocks at its leaf nodes. On each
+ non-leaf node is a single bit - a 0 indicates that
+ older blocks are in the upper child tree while a 1
+ indicates that older blocks are in the lower child
+ tree.
+ When replacing a block, PLRU will choose the one
+ which is oldest according to those bits. Then all
+ bits along the path are flipped to mark it as the
+ most recent.
+ When accessing any block that is stored in the
+ cache, PLRU will update all bits along the path to
+ the new block so they correctly identify it as the
+ newest block.
+ Note that when using PLRU, associativity must be a
+ power of 2 since PLRU uses a binary tree in its
+ state.
+
+
+ You can also get a visualization of the cache by
+ selecting it in the drop down menu in the control
+ bar. Note that for performance reasons, this option
+ becomes unavailabe if the cache gets too big. Even
+ with the visualization disabled, you should not make
+ the cache too big since the site may become
+ unresponsive.
+
+
+ When using a data cache, misaligned access to the
+ memory is not allowed because it would be unclear
+ what exactly should happen in the cache. For
+ example, the following piece of code would not work
+ since the accessed value crosses a word boundary:
+
+
lw x1, -5(x0)
+
+
+
+
+
+
+
+
+
+
+ Environment calls (ECALLs) can be used for
+ interacting with the environment - currently, ECALLs
+ can be used for printing to the console or stopping
+ the simulation. Each ECALL has a different code
+ which must be loaded into register a7.
+ Some ECALLs also require an argument which must be
+ loaded into register a0. The supported
+ ECALLs are identical to those of Ripes.
+
-
- Note that our visualization of the pipeline during an ECALL is not
- fully correct. The pipeline might get flushed unnecessarily and we
- also dont halt the pipeline until the ECALL has finished - instead,
- the entire ecall is being executed in a single cycle (in the execute
- stage).
-
+
+ Note that our visualization of the pipeline during
+ an ECALL is not fully correct. The pipeline might
+ get flushed unnecessarily and we also dont halt the
+ pipeline until the ECALL has finished - instead, the
+ entire ecall is being executed in a single cycle (in
+ the execute stage).
+
-
-
-
-
-
a7
-
a0
-
Description
-
-
-
-
-
1
-
integer to print
-
Prints a0 as signed integer.
-
-
-
2
-
float to print
-
- Prints a0 as a floating point number.
-
-
-
-
4
-
string to print
-
- Prints the null terminated string whose first
- character is stored at the address in
- a0.
-
-
-
-
10
-
-
-
Stops the simulation with code 0.
-
-
-
11
-
char to print
-
Prints a0 as ASCII character
-
-
-
34
-
hex to print
-
Prints a0 as hexadecimal nuber
-
-
-
35
-
binary to print
-
Prints a0 as binary number.
-
-
-
36
-
integer to print
-
Prints a0 as unsigned integer.
-
-
-
93
-
exit code
-
- Stops the simulation with code in a0.
-
-
-
-
+
+
+
+
+
a7
+
a0
+
Description
+
+
+
+
+
1
+
integer to print
+
+ Prints a0 as signed
+ integer.
+
+
+
+
2
+
float to print
+
+ Prints a0 as a floating
+ point number.
+
+
+
+
4
+
string to print
+
+ Prints the null terminated string
+ whose first character is stored at
+ the address in
+ a0.
+
+
+
+
10
+
-
+
+ Stops the simulation with code 0.
+
+
+
+
11
+
char to print
+
+ Prints a0 as ASCII
+ character
+
+
+
+
34
+
hex to print
+
+ Prints a0 as
+ hexadecimal nuber
+
+
+
+
35
+
binary to print
+
+ Prints a0 as binary
+ number.
+
+
+
+
36
+
integer to print
+
+ Prints a0 as unsigned
+ integer.
+
+
+
+
93
+
exit code
+
+ Stops the simulation with code in
+ a0.
+
+
+
+
+
+
+
+
+
From 8a01b7c97eab17d8bd48992ded4d89296bd4bd7a Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Thu, 25 Apr 2024 19:15:04 +0200
Subject: [PATCH 078/138] finish accordion riscv help page
---
webgui/src/components/riscv/RiscvHelp.vue | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index f8e53b0..c2b16dc 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -7,8 +7,8 @@
This simulator supports a subset of the RISC-V32 ISA. The supported
instructions are listed below.
-
-
+
+
-
-
Other
-
-
+
+
Other
+
+
@@ -1479,5 +1480,4 @@ addi x3, x3, 1 # This line is never reached
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index 9c8d4a3..ec98eaa 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -1,338 +1,341 @@
-[
- {
- "Instruction":"ADD rd, rs1, rs2",
- "Operation":"rd = rs1 + rs2",
- "Notes":null,
- "Format":"R-type"
- },
- {
- "Instruction":"SUB rd, rs1, rs2",
- "Operation":"rd = rs1 - rs2",
- "Notes":null,
- "Format":"R-type"
- },
- {
- "Instruction":"SLL rd, rs1, rs2",
- "Operation":"rd = rs1 << rs2",
- "Notes":null,
- "Format":"R-type"
- },
- {
- "Instruction":"SRL rd, rs1, rs2",
- "Operation":"rd = rs1 >> rs2",
- "Notes":"Logical right shift",
- "Format":"R-type"
- },
- {
- "Instruction":"SRA rd, rs1, rs2",
- "Operation":"rd = rs1 >>a rs2",
- "Notes":"Arithmetic right shift",
- "Format":"R-type"
- },
- {
- "Instruction":"SLT rd, rs1, rs2",
- "Operation":"rd = rs1 > imm",
- "Notes":"Logical right shift. imm is unsigned, with a length of 5 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"SRAI rd, rs1, imm",
- "Operation":"rd = rs1 >>a imm",
- "Notes":"Arithmetic right shift. imm is unsigned, with a length of 5 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load byte. rd is sign extended to 32 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LH rd, rs1, imm\nLH rd, imm(rs1)\nLH rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load two bytes. rd is sign extended to 32 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LW rd, rs1, imm\nLW rd, imm(rs1)\nLW rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load four bytes. rd is sign extended to 32 bits",
- "Format":"I-type"
- },
- {
- "Instruction":"LBU rd, rs1, imm\nLBU rd, imm(rs1)\nLBU rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load byte",
- "Format":"I-type"
- },
- {
- "Instruction":"LHU rd, rs1, imm\nLHU rd, imm(rs1)\nLHU rd, var[index]",
- "Operation":"rd = M[rs1 + imm] rd = var[index]",
- "Notes":"Load two bytes",
- "Format":"I-type"
- },
- {
- "Instruction":"JALR rd, rs1, imm",
- "Operation":"rd = PC + 4; PC = rs1 + imm",
- "Notes":"Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
- "Format":"I-type"
- },
- {
- "Instruction":"ECALL",
- "Operation":"environment call",
- "Notes":"See section ECALLs.",
- "Format":"I-type"
- },
- {
- "Instruction":"SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
- "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
- "Notes":"Store byte. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
- "Format":"S-type"
- },
- {
- "Instruction":"SH rs1, rs2, imm\nSH rs1, imm(rs2)\nSH rs1, var[index], rs2",
- "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
- "Notes":"Store two bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
- "Format":"S-type"
- },
- {
- "Instruction":"SW rs1, rs2, imm\nSW rs1, imm(rs2)\nSW rs1, var[index], rs2",
- "Operation":"M[rs2 + imm] = rs1 var[index] = rs1",
- "Notes":"Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
- "Format":"S-type"
- },
- {
- "Instruction":"BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
- "Operation":"if (rs1 == rs2) PC = PC + imm",
- "Notes":"Branch if equal",
- "Format":"B-type"
- },
- {
- "Instruction":"BNE rs1, rs2, imm\nBNE rs1, rs2, label+offset",
- "Operation":"if (rs1 != rs2) PC = PC + imm",
- "Notes":"Branch if not equal",
- "Format":"B-type"
- },
- {
- "Instruction":"BLT rs1, rs2, imm\nBLT rs1, rs2, label+offset",
- "Operation":"if (rs1 =s rs2) PC = PC + imm",
- "Notes":"Branch if greater than or equal",
- "Format":"B-type"
- },
- {
- "Instruction":"BLTU rs1, rs2, imm\nBLTU rs1, rs2, label+offset",
- "Operation":"if (rs1 =u rs2) PC = PC + imm",
- "Notes":"Branch if greater than or equal (unsigned)",
- "Format":"B-type"
- },
- {
- "Instruction":"LUI rd, imm",
- "Operation":"rd = imm << 12",
- "Notes":null,
- "Format":"U"
- },
- {
- "Instruction":"AUIPC rd, imm",
- "Operation":"rd = PC + (imm << 12)",
- "Notes":null,
- "Format":"U"
- },
- {
- "Instruction":"JAL rd, addr\nJAL rd, label+offset",
- "Operation":"rd = PC + 4; PC = addr",
- "Notes":"Jump and link. rd is set to the address of the instruction following the jump.",
- "Format":"J-type"
- },
- {
- "Instruction":"CSRRW rd, csr, rs1",
- "Operation":"rd = csr; csr = rs1",
- "Notes":"Atomic read\/write",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRS rd, csr, rs1",
- "Operation":"rd = csr; csr = csr | rs1",
- "Notes":"Atomic read\/set. rs1 serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRC rd, csr, rs1",
- "Operation":"rd = csr; csr = csr & ~rs1",
- "Notes":"Atomic read\/clear. rs1 serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRWI rd, csr, uimm",
- "Operation":"rd = csr; csr = uimm",
- "Notes":"Atomic read\/write",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRSI rd, csr, uimm",
- "Operation":"rd = csr; csr = csr | uimm",
- "Notes":"Atomic read\/set. uimm serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"CSRRCI rd, csr, uimm",
- "Operation":"rd = csr; csr = csr & ~uimm",
- "Notes":"Atomic read\/clear. uimm serves as a bit mask",
- "Format":"CSR"
- },
- {
- "Instruction":"NOP",
- "Operation":"-",
- "Notes":"No operation. Translated to ADDI x0, x0, 0",
- "Format":"Pseudo"
- },
- {
- "Instruction":"LA rd, var[index]",
- "Operation":"rd = &var[index]",
- "Notes":"Load variable address into rd",
- "Format":"Pseudo"
- },
- {
- "Instruction":"LI rd, imm",
- "Operation":"rd = imm",
- "Notes":"Load 32 bit immediate into rd",
- "Format":"Pseudo"
- },
- {
- "Instruction":"MV rd, rs",
- "Operation":"rd = rs",
- "Notes":"Translated to ADDI rd, rs, 0",
- "Format":"Pseudo"
- }
-]
+{
+ "all": [
+ {
+ "Instruction": "ADD rd, rs1, rs2",
+ "Operation": "rd = rs1 + rs2",
+ "Notes": null,
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SUB rd, rs1, rs2",
+ "Operation": "rd = rs1 - rs2",
+ "Notes": null,
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SLL rd, rs1, rs2",
+ "Operation": "rd = rs1 << rs2",
+ "Notes": null,
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SRL rd, rs1, rs2",
+ "Operation": "rd = rs1 >> rs2",
+ "Notes": "Logical right shift",
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SRA rd, rs1, rs2",
+ "Operation": "rd = rs1 >>a rs2",
+ "Notes": "Arithmetic right shift",
+ "Format": "R-type"
+ },
+ {
+ "Instruction": "SLT rd, rs1, rs2",
+ "Operation": "rd = rs1 > imm",
+ "Notes": "Logical right shift. imm is unsigned, with a length of 5 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "SRAI rd, rs1, imm",
+ "Operation": "rd = rs1 >>a imm",
+ "Notes": "Arithmetic right shift. imm is unsigned, with a length of 5 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load byte. rd is sign extended to 32 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LH rd, rs1, imm\nLH rd, imm(rs1)\nLH rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load two bytes. rd is sign extended to 32 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LW rd, rs1, imm\nLW rd, imm(rs1)\nLW rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load four bytes. rd is sign extended to 32 bits",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LBU rd, rs1, imm\nLBU rd, imm(rs1)\nLBU rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load byte",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "LHU rd, rs1, imm\nLHU rd, imm(rs1)\nLHU rd, var[index]",
+ "Operation": "rd = M[rs1 + imm] rd = var[index]",
+ "Notes": "Load two bytes",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "JALR rd, rs1, imm",
+ "Operation": "rd = PC + 4; PC = rs1 + imm",
+ "Notes": "Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "ECALL",
+ "Operation": "environment call",
+ "Notes": "See section ECALLs.",
+ "Format": "I-type"
+ },
+ {
+ "Instruction": "SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
+ "Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes": "Store byte. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format": "S-type"
+ },
+ {
+ "Instruction": "SH rs1, rs2, imm\nSH rs1, imm(rs2)\nSH rs1, var[index], rs2",
+ "Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes": "Store two bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format": "S-type"
+ },
+ {
+ "Instruction": "SW rs1, rs2, imm\nSW rs1, imm(rs2)\nSW rs1, var[index], rs2",
+ "Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
+ "Notes": "Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
+ "Format": "S-type"
+ },
+ {
+ "Instruction": "BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
+ "Operation": "if (rs1 == rs2) PC = PC + imm",
+ "Notes": "Branch if equal",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "BNE rs1, rs2, imm\nBNE rs1, rs2, label+offset",
+ "Operation": "if (rs1 != rs2) PC = PC + imm",
+ "Notes": "Branch if not equal",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "BLT rs1, rs2, imm\nBLT rs1, rs2, label+offset",
+ "Operation": "if (rs1 =s rs2) PC = PC + imm",
+ "Notes": "Branch if greater than or equal",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "BLTU rs1, rs2, imm\nBLTU rs1, rs2, label+offset",
+ "Operation": "if (rs1 =u rs2) PC = PC + imm",
+ "Notes": "Branch if greater than or equal (unsigned)",
+ "Format": "B-type"
+ },
+ {
+ "Instruction": "LUI rd, imm",
+ "Operation": "rd = imm << 12",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "AUIPC rd, imm",
+ "Operation": "rd = PC + (imm << 12)",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "JAL rd, addr\nJAL rd, label+offset",
+ "Operation": "rd = PC + 4; PC = addr",
+ "Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
+ "Format": "J-type"
+ },
+ {
+ "Instruction": "CSRRW rd, csr, rs1",
+ "Operation": "rd = csr; csr = rs1",
+ "Notes": "Atomic read/write",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRS rd, csr, rs1",
+ "Operation": "rd = csr; csr = csr | rs1",
+ "Notes": "Atomic read/set. rs1 serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRC rd, csr, rs1",
+ "Operation": "rd = csr; csr = csr & ~rs1",
+ "Notes": "Atomic read/clear. rs1 serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRWI rd, csr, uimm",
+ "Operation": "rd = csr; csr = uimm",
+ "Notes": "Atomic read/write",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRSI rd, csr, uimm",
+ "Operation": "rd = csr; csr = csr | uimm",
+ "Notes": "Atomic read/set. uimm serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "CSRRCI rd, csr, uimm",
+ "Operation": "rd = csr; csr = csr & ~uimm",
+ "Notes": "Atomic read/clear. uimm serves as a bit mask",
+ "Format": "CSR"
+ },
+ {
+ "Instruction": "NOP",
+ "Operation": "-",
+ "Notes": "No operation. Translated to ADDI x0, x0, 0",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LA rd, var[index]",
+ "Operation": "rd = &var[index]",
+ "Notes": "Load variable address into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LI rd, imm",
+ "Operation": "rd = imm",
+ "Notes": "Load 32 bit immediate into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "MV rd, rs",
+ "Operation": "rd = rs",
+ "Notes": "Translated to ADDI rd, rs, 0",
+ "Format": "Pseudo"
+ }
+ ],
+ "other": []
+}
From 4443e50d193c8164dfefd3ac4d5a4c812b592892 Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Fri, 26 Apr 2024 12:32:16 +0200
Subject: [PATCH 082/138] split instructions into sections
---
webgui/src/components/riscv/RiscvHelp.vue | 1135 +--------------------
webgui/src/data/riscv_instructions.json | 107 +-
2 files changed, 99 insertions(+), 1143 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index d694144..c7069d8 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -2,7 +2,6 @@
@@ -12,1158 +11,110 @@ const fields = ["Instruction", "Operation", "Notes", "Format"];
This simulator supports a subset of the RISC-V32 ISA. The supported
instructions are listed below.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADD rd, rs1, rs2
-
-
- rd = rs1 + rs2
-
-
-
-
-
- SUB rd, rs1, rs2
-
-
- rd = rs1 - rs2
-
-
-
-
-
- SLL rd, rs1, rs2
-
-
- rd = rs1 << rs2
-
-
-
-
-
- SRL rd, rs1, rs2
-
-
- rd = rs1 >> rs2
-
-
Logical right shift
-
-
-
- SRA rd, rs1, rs2
-
-
- rd = rs1 >>a rs2
-
-
Arithmetic right shift
-
-
-
- SLT rd, rs1, rs2
-
-
- rd = rs1 <s rs2
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in rs2,
- otherwise 0 (both values are treated
- as signed)
-
-
-
-
- SLTU rd, rs1, rs2
-
-
- rd = rs1 <u rs2
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in rs2,
- otherwise 0 (both values are treated
- as unsigned)
-
-
-
-
- AND rd, rs1, rs2
-
-
- rd = rs1 & rs2
-
-
-
-
-
- OR rd, rs1, rs2
-
-
- rd = rs1 | rs2
-
-
-
-
-
- XOR rd, rs1, rs2
-
-
- rd = rs1 ^ rs2
-
-
-
-
-
- MUL rd, rs1, rs2
-
-
- rd = rs1 * rs2
-
-
- (M), places the lower 32 bits of the
- result in the destination register
-
-
-
-
- MULH rd, rs1, rs2
-
-
- rd = rs1 s*s rs2
-
-
- (M), places the upper 32 bits of the
- result in the destination register,
- both rs1 and rs2 are treated as
- signed
-
-
-
-
- MULHU rd, rs1, rs2
-
-
- rd = rs1 u*u rs2
-
-
- (M), places the upper 32 bits of the
- result in the destination register,
- both rs1 and rs2 are treated as
- unsigned
-
-
-
-
- MULHSU rd, rs1, rs2
-
-
- rd = rs1 s*u rs2
-
-
- (M), places the upper 32 bits of the
- result in the destination register,
- rs1 treated as signed, rs2 treated
- as unsigned
-
-
-
-
- DIV rd, rs1, rs2
-
-
- rd = rs1 /s rs2
-
-
(M), signed integer division
-
-
-
- DIVU rd, rs1, rs2
-
-
- rd = rs1 /u rs2
-
-
(M), unsigned integer division
-
-
-
- REM rd, rs1, rs2
-
-
- rd = rs1 %s rs2
-
-
- (M), remainder of signed integer
- division
-
-
-
-
- REMU rd, rs1, rs2
-
-
- rd = rs1 %u rs2
-
-
- (M), remainder of unsigned integer
- division
-
-
-
-
-
-
- Note: Instructions marked with (M) are part of the
- "M" Standard Extension for Integer Multiplication
- and Division.
-
-
-
-
-
-
-
-
-
-
-
- Unless otherwise specified, the immediate
- (imm) has a length of 12 bits and is
- sign extended to 32 bits.
-
- var is a variable name,
- index is an optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- ADDI rd, rs1, imm
-
-
- rd = rs1 + imm
-
-
-
-
-
- SLTI rd, rs1, imm
-
-
- rd = rs1 <s imm
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in imm,
- otherwise 0 (both values are treated
- as signed)
-
-
-
-
- SLTIU rd, rs1, imm
-
-
- rd = rs1 <u imm
-
-
- Set rd to 1 if the
- value in rs1 is less
- than the value in imm,
- otherwise 0 (both values are treated
- as unsigned)
-
-
-
-
- ANDI rd, rs1, imm
-
-
- rd = rs1 & imm
-
-
-
-
-
- ORI rd, rs1, imm
-
-
- rd = rs1 | imm
-
-
-
-
-
- XORI rd, rs1, imm
-
-
- rd = rs1 ^ imm
-
-
-
-
-
- SLLI rd, rs1, imm
-
-
- rd = rs1 << imm
-
-
- imm is unsigned, with a
- length of 5 bits
-
-
-
-
- SRLI rd, rs1, imm
-
-
- rd = rs1 >> imm
-
-
- Logical right shift. imm
- is unsigned, with a length of 5 bits
-
-
-
-
- SRAI rd, rs1, imm
-
-
- rd = rs1 >>a imm
-
-
- Arithmetic right shift. imm
- is unsigned, with a length of 5 bits
-
- Jump and link register.
- rd is set to the
- address of the instruction following
- the jump. The jump target is
- rs1 + imm
- with the least significant bit
- cleared.
-
- The immediate (imm) has a length of 20
- bits and is sign extended to 32 bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- LUI rd, imm
-
-
- rd = imm << 12
-
-
-
-
-
- AUIPC rd, imm
-
-
- rd = PC + (imm <<
- 12)
-
-
-
-
-
-
-
-
-
+
-
+
-
- The address to jump to (addr), is
- encoded relative to the current pc in a 21 bit
- immediate that is sign extended to 32 bits and added
- to the current pc.
- Offsets are optional, and in hexadecimal format.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- JAL rd, addr
- JAL rd, label+offset
-
-
- rd = PC + 4; PC = addr
-
-
- Jump and link.
- rd is set to the
- address of the instruction following
- the jump.
-
-
-
-
-
+
-
+
-
- Currently not implemented in 5-stage pipeline
- mode.
-
- The unsigned immediate (uimm) has a
- length of 5 bits.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- CSRRW rd, csr, rs1
-
-
- rd = csr; csr = rs1
-
-
Atomic read/write
-
-
-
- CSRRS rd, csr, rs1
-
-
- rd = csr; csr = csr | rs1
-
-
- Atomic read/set.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRC rd, csr, rs1
-
-
- rd = csr; csr = csr &
- ~rs1
-
-
- Atomic read/clear.
- rs1
- serves as a bit mask
-
-
-
-
- CSRRWI rd, csr, uimm
-
-
- rd = csr; csr = uimm
-
-
Atomic read/write
-
-
-
- CSRRSI rd, csr, uimm
-
-
- rd = csr; csr = csr |
- uimm
-
-
- Atomic read/set.
- uimm
- serves as a bit mask
-
-
-
-
- CSRRCI rd, csr, uimm
-
-
- rd = csr; csr = csr &
- ~uimm
-
-
- Atomic read/clear.
- uimm
- serves as a bit mask
-
-
-
-
-
+
-
+
-
- var is a variable name,
- index is an optional array index.
-
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- NOP
-
-
-
-
- No operation. Translated to
- ADDI x0, x0, 0
-
-
-
-
- LA rd, var[index]
-
-
- rd = &var[index]
-
-
- Load variable address into
- rd
-
-
-
-
- LI rd, imm
-
-
- rd = imm
-
-
- Load 32 bit immediate into
- rd
-
-
-
-
- MV rd, rs
-
-
rd = rs
-
- Translated to
- ADDI rd, rs, 0
-
-
-
-
-
+
-
+
-
-
-
-
-
Instruction
-
Operation
-
Notes
-
-
-
-
-
- EBREAK
-
-
-
-
- Recognized but currently not
- implemented
-
-
-
-
- FENCE rd, rs1
-
-
-
-
- Recognized but currently not
- implemented
-
-
-
-
-
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index ec98eaa..18aafdb 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -1,5 +1,5 @@
{
- "all": [
+ "computational": [
{
"Instruction": "ADD rd, rs1, rs2",
"Operation": "rd = rs1 + rs2",
@@ -162,6 +162,44 @@
"Notes": "Arithmetic right shift. imm is unsigned, with a length of 5 bits",
"Format": "I-type"
},
+ {
+ "Instruction": "LUI rd, imm",
+ "Operation": "rd = imm << 12",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "AUIPC rd, imm",
+ "Operation": "rd = PC + (imm << 12)",
+ "Notes": null,
+ "Format": "U"
+ },
+ {
+ "Instruction": "NOP",
+ "Operation": "-",
+ "Notes": "No operation. Translated to ADDI x0, x0, 0",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LA rd, var[index]",
+ "Operation": "rd = &var[index]",
+ "Notes": "Load variable address into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "LI rd, imm",
+ "Operation": "rd = imm",
+ "Notes": "Load 32 bit immediate into rd",
+ "Format": "Pseudo"
+ },
+ {
+ "Instruction": "MV rd, rs",
+ "Operation": "rd = rs",
+ "Notes": "Translated to ADDI rd, rs, 0",
+ "Format": "Pseudo"
+ }
+ ],
+ "memory-accesses": [
{
"Instruction": "LB rd, rs1, imm\nLB rd, imm(rs1)\nLB rd, var[index]",
"Operation": "rd = M[rs1 + imm] rd = var[index]",
@@ -192,18 +230,6 @@
"Notes": "Load two bytes",
"Format": "I-type"
},
- {
- "Instruction": "JALR rd, rs1, imm",
- "Operation": "rd = PC + 4; PC = rs1 + imm",
- "Notes": "Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
- "Format": "I-type"
- },
- {
- "Instruction": "ECALL",
- "Operation": "environment call",
- "Notes": "See section ECALLs.",
- "Format": "I-type"
- },
{
"Instruction": "SB rs1, rs2, imm\nSB rs1, imm(rs2)\nSB rs1, var[index], rs2",
"Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
@@ -221,6 +247,14 @@
"Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
"Notes": "Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format": "S-type"
+ }
+ ],
+ "jumps and branches": [
+ {
+ "Instruction": "JALR rd, rs1, imm",
+ "Operation": "rd = PC + 4; PC = rs1 + imm",
+ "Notes": "Jump and link register. rd is set to the address of the instruction following the jump. The jump target is rs1 + imm with the least significant bit cleared.",
+ "Format": "I-type"
},
{
"Instruction": "BEQ rs1, rs2, imm\nBEQ rs1, rs2, label+offset",
@@ -258,23 +292,19 @@
"Notes": "Branch if greater than or equal (unsigned)",
"Format": "B-type"
},
- {
- "Instruction": "LUI rd, imm",
- "Operation": "rd = imm << 12",
- "Notes": null,
- "Format": "U"
- },
- {
- "Instruction": "AUIPC rd, imm",
- "Operation": "rd = PC + (imm << 12)",
- "Notes": null,
- "Format": "U"
- },
{
"Instruction": "JAL rd, addr\nJAL rd, label+offset",
"Operation": "rd = PC + 4; PC = addr",
"Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
"Format": "J-type"
+ }
+ ],
+ "system instructions": [
+ {
+ "Instruction": "ECALL",
+ "Operation": "environment call",
+ "Notes": "See section ECALLs.",
+ "Format": "I-type"
},
{
"Instruction": "CSRRW rd, csr, rs1",
@@ -311,31 +341,6 @@
"Operation": "rd = csr; csr = csr & ~uimm",
"Notes": "Atomic read/clear. uimm serves as a bit mask",
"Format": "CSR"
- },
- {
- "Instruction": "NOP",
- "Operation": "-",
- "Notes": "No operation. Translated to ADDI x0, x0, 0",
- "Format": "Pseudo"
- },
- {
- "Instruction": "LA rd, var[index]",
- "Operation": "rd = &var[index]",
- "Notes": "Load variable address into rd",
- "Format": "Pseudo"
- },
- {
- "Instruction": "LI rd, imm",
- "Operation": "rd = imm",
- "Notes": "Load 32 bit immediate into rd",
- "Format": "Pseudo"
- },
- {
- "Instruction": "MV rd, rs",
- "Operation": "rd = rs",
- "Notes": "Translated to ADDI rd, rs, 0",
- "Format": "Pseudo"
}
- ],
- "other": []
+ ]
}
From 3b5ce7779b1b8d5b5e73eb5a9fb9ae79bd29694b Mon Sep 17 00:00:00 2001
From: MartinRoehm
Date: Fri, 26 Apr 2024 15:29:58 +0200
Subject: [PATCH 083/138] reordering and adding notes back
---
webgui/src/components/riscv/RiscvHelp.vue | 47 +++++++++++++++++++++++
webgui/src/data/riscv_instructions.json | 24 ++++++------
2 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index c7069d8..876a274 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -34,6 +34,20 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
+
+ Notes:
+ - Instructions marked with (M) are part of the "M”
+ Standard Extension for Integer Multiplication and
+ Division.
+
+ - Unless otherwise specified, the immediate
+ (imm) of I-type instructions has a
+ length of 12 bits and is sign extended to 32 bits.
+
+ - The immediate (imm) of U-Type
+ instructions has a length of 20 bits and is sign
+ extended to 32 bits.
+
+ Notes:
+ - The immediate (imm) of the instructions in this
+ paragraph has a length of 12 bits and is sign
+ extended to 32 bits.
+
+ - var is a variable name,
+ index is an optional array index.
+
@@ -88,6 +111,20 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
riscv_instructions['jumps and branches']
"
/>
+
+ Notes:
+ - JAL instructions encode the address to jump to
+ (addr), relative to the current pc in a
+ 21 bit immediate that is sign extended to 32 bits
+ and added to the current pc.
+ - The JALR immediate (imm) has a length
+ of 12 bits and is sign extended to 32 bits.
+ - The immediate (imm ) of B-type
+ instructions has a length of 13 bits and is sign
+ extended to 32 bits.
+ - offset is optional, and in
+ hexadecimal format.
+
+ Notes:
+ -
+ CSR Currently not implemented in 5-stage
+ pipeline mode.
+ - The unsigned immediate (uimm) has a
+ length of 5 bits.
+
diff --git a/webgui/src/data/riscv_instructions.json b/webgui/src/data/riscv_instructions.json
index 18aafdb..5fe05a4 100644
--- a/webgui/src/data/riscv_instructions.json
+++ b/webgui/src/data/riscv_instructions.json
@@ -180,12 +180,6 @@
"Notes": "No operation. Translated to ADDI x0, x0, 0",
"Format": "Pseudo"
},
- {
- "Instruction": "LA rd, var[index]",
- "Operation": "rd = &var[index]",
- "Notes": "Load variable address into rd",
- "Format": "Pseudo"
- },
{
"Instruction": "LI rd, imm",
"Operation": "rd = imm",
@@ -247,9 +241,21 @@
"Operation": "M[rs2 + imm] = rs1 var[index] = rs1",
"Notes": "Store four bytes. If a variable is modified, rs2 is used as a temporary register, that will be overwritten.",
"Format": "S-type"
+ },
+ {
+ "Instruction": "LA rd, var[index]",
+ "Operation": "rd = &var[index]",
+ "Notes": "Load variable address into rd",
+ "Format": "Pseudo"
}
],
"jumps and branches": [
+ {
+ "Instruction": "JAL rd, addr\nJAL rd, label+offset",
+ "Operation": "rd = PC + 4; PC = addr",
+ "Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
+ "Format": "J-type"
+ },
{
"Instruction": "JALR rd, rs1, imm",
"Operation": "rd = PC + 4; PC = rs1 + imm",
@@ -291,12 +297,6 @@
"Operation": "if (rs1 >=u rs2) PC = PC + imm",
"Notes": "Branch if greater than or equal (unsigned)",
"Format": "B-type"
- },
- {
- "Instruction": "JAL rd, addr\nJAL rd, label+offset",
- "Operation": "rd = PC + 4; PC = addr",
- "Notes": "Jump and link. rd is set to the address of the instruction following the jump.",
- "Format": "J-type"
}
],
"system instructions": [
From 9b36ddcc624f43e59a2cbf6f22e84e2d73888841 Mon Sep 17 00:00:00 2001
From: Michael Kuhn
Date: Fri, 26 Apr 2024 15:44:45 +0200
Subject: [PATCH 084/138] update text
---
webgui/src/components/riscv/RiscvHelp.vue | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/webgui/src/components/riscv/RiscvHelp.vue b/webgui/src/components/riscv/RiscvHelp.vue
index 876a274..1a2e0d0 100644
--- a/webgui/src/components/riscv/RiscvHelp.vue
+++ b/webgui/src/components/riscv/RiscvHelp.vue
@@ -8,8 +8,8 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
RISC-V
Instructions
- This simulator supports a subset of the RISC-V32 ISA. The supported
- instructions are listed below.
+ This simulator supports a subset of the RISC-V RV32IM ISA. The
+ supported instructions are listed below.
- Notes:
- - Instructions marked with (M) are part of the "M”
- Standard Extension for Integer Multiplication and
- Division.
-
- - Unless otherwise specified, the immediate
- (imm) of I-type instructions has a
- length of 12 bits and is sign extended to 32 bits.
-
- - The immediate (imm) of U-Type
- instructions has a length of 20 bits and is sign
- extended to 32 bits.
-
+
Notes:
+
+
+ Instructions marked with (M) are part of the "M”
+ Standard Extension for Integer Multiplication
+ and Division.
+
+
+ Unless otherwise specified, the immediate
+ (imm) of I-type instructions has a
+ length of 12 bits and is sign extended to 32
+ bits.
+
+
+ The immediate (imm) of U-Type
+ instructions has a length of 20 bits and is sign
+ extended to 32 bits.
+
- Notes:
- - The immediate (imm) of the instructions in this
- paragraph has a length of 12 bits and is sign
- extended to 32 bits.
-
- - var is a variable name,
- index is an optional array index.
-
+
Notes:
+
+
+ The immediate (imm) of the instructions in this
+ paragraph has a length of 12 bits and is sign
+ extended to 32 bits.
+
+
+ var is a variable name,
+ index is an optional array index.
+
+
@@ -111,20 +119,29 @@ import RiscvHelpTable from "./RiscvHelpTable.vue";
riscv_instructions['jumps and branches']
"
/>
-
- Notes:
- - JAL instructions encode the address to jump to
- (addr), relative to the current pc in a
- 21 bit immediate that is sign extended to 32 bits
- and added to the current pc.
- - The JALR immediate (imm) has a length
- of 12 bits and is sign extended to 32 bits.
- - The immediate (imm ) of B-type
- instructions has a length of 13 bits and is sign
- extended to 32 bits.
- - offset is optional, and in
- hexadecimal format.
-
+
Notes:
+
+
+ JAL instructions encode the address to jump to
+ (addr), relative to the current pc
+ in a 21 bit immediate that is sign extended to
+ 32 bits and added to the current pc.
+
+
+ The JALR immediate (imm) has a
+ length of 12 bits and is sign extended to 32
+ bits.
+
+
+ The immediate (imm ) of B-type
+ instructions has a length of 13 bits and is sign
+ extended to 32 bits.
+
+
+ offset is optional, and in
+ hexadecimal format.
+