Skip to content

kohshi54/tiny-parrot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tiny-parrot

RV32I simulator in C++.

Registers

image
https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf#page=22

ABI

image
https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf#page=121

Instruction Format

image
https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf#page=116

Basic Instruction Set

image
https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf#page=116

  • note that instruction classifiction is based on not only opcode but also with funct7 and fucnt3.
  • also, RISC-V contains pseudo-instructions that is more complex instructions that will be translated into within RISC-V instruction sets by assembler.
    https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf#page=122 \
    • For instance :
      mv a0,a5 -> add a0, a5, zero
      

I-type Instruction

ADDI

ADDI rd, rs1, imm -> rd = rs1 + imm
  • equivalent to mv instruction when used with addi rd, rs1, 0. RISC-V does not have mv instruction, so that assembler changes mv to addi.

ANDI

ANDI rd, rs1, imm -> rd = rs1 & imm

ORI

ORI rd, rs1, imm -> rd = rs1 | imm

XORI

XORI rd, rs1, imm -> rd = rs1 ^ imm

SLLI

SLL rd, rs1, imm -> rd = rs1 << imm
  • note that in order to perform logical operation, the operand value should be cast to (uint 32).

SRAI

SRA rd, rs1, imm -> rd = rs1 >> imm
  • perform arithmatic shift, which means sign extension is operated during the operatin.

SRLI

SRL rd, rs1, imm -> rd = rs1 >> imm
  • note that in order to perform logical operation, the operand value should be cast to (uint 32).

SLTI

SLTI rd, rs1, imm -> rd = rs1 << imm

SLTIU

SLTIU rd, rs1, rs2 -> rd = (uint32_t)rs1 < (uint32_t)imm

JALR

JALR rd, rs1, offset -> pc = rs1 + offset; rd = pc + 4
  • note that JAL is J-type instruction, and JALR is I-type instruction.

LW

LW rd, rs1, offset -> rd = mem[rs1 + offset]

LH

LH rd, rs1, offset -> rd = mem[rs1 + offset] & 0x0000ffff

LB

LB rd, rs1, offset -> rd = mem[rs1 + offset] & 0x000000ff

LHU

LHU rd, rs1, offset -> rd = (uint32_t)mem[rs1 + offset] & 0x0000ffff

LBU

LBU rd, rs1, offset -> rd = (uint32_t)mem[rs1 + offset] & 0x000000ff

R-type Instruction

ADD

ADD rd, rs1, rs2 -> rd = rs1 + rs2

SUB

SUB rd, rs1, rs2 -> rd = rs1 - rs2

AND

AND rd, rs1, rs2 -> rd = rs1 & rs2
  • note that the AND and similar operation in RISC-V is bitwise operation, not logical.

OR

OR rd, rs1, rs2 -> rd = rs1 | rs2

XOR

XOR rd, rs1, rs2 -> rd = rs1 ^ rs2

SLL

SLL rd, rs1, rs2 -> rd = rs1 << rs2
  • note that in order to perform logical operation, the operand value should be cast to (uint 32).

SRA

SRA rd, rs1, rs2 -> rd = rs1 >> rs2

SRL

SRL rd, rs1, rs2 -> rd = rs1 >> rs2
  • note that in order to perform logical operation, the operand value should be cast to (uint 32).

SLT

SLT rd, rs1, rs2 -> rd = rs1 < rs2

SLTU

SLTU rd, rs1, rs2 -> rd = (uint32_t)rs1 < (uint32_t)rs2

U-type Instruction

LUI

LUI rd, imm -> rd = (int32_t)imm << 12
  • note that imm is sign extended before shift left by 12 bits.

AUIPC

AUIPC rd, imm -> rd = pc + ((int32_t)imm << 12)
  • note that imm is sign extended before shift left by 12 bits.

B-type Instruction

BEQ

BEQ rs1, rs2, offset -> if (rs1 == rs2) pc += offset
  • note that offset is 12 bits length, which means the offset range is within ±4 KiB.

BNE

BNE rs1, rs2, offset -> if (rs1 != rs2) pc += offset

BLT

BLT rs1, rs2, offset -> if (rs1 < rs2) pc += offset

BGE

BGE rs1, rs2, offset -> if (rs1 >= rs2) pc += offset
  • not that bge include equality (bge stands for branch if greater or equal to).

BLTU

BLTU rs1, rs2, offset -> if ((uint32_t)rs1 < (uint32_t)rs2) pc += offset

BGEU

BGEU rs1, rs2, offset -> if ((uint32_t)rs1 >= (uint32_t)rs2) pc += offset

J-type Instruction

JAL

JAL rd, offset -> pc += offset; rd = pc + 4

S-type Instruction

SW

SW rs1, rs2, offset -> mem[rs2 + offset] = rs1 (*original: mem[rs1 + offset] = rs2)

SH

SH rs1, rs2, offset -> mem[rs2 + offset] = rs1 & 0x0000ffff (*original: mem[rs1 + offset] = rs2 & 0x0000ffff)
  • note that 0x0000ffff = half word which is 16 bits. one word is 4 bytes. in hex format 1 bit stand for 4 bits in binary, so 2 digits of hex is 1 byte. threfore in order to achive 32 bit, it needs 2 * 4 = 8 digits in hex.

SB

SB rs1, rs2, offset -> mem[rs2 + offset] = rs1 & 0x0000000ff (*original: SB rs1, rs2, offset -> mem[rs1 + offset] = rs2 & 0x0000000ff)

About

RV32I Simulator

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published