diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | instructions.py | 145 | ||||
-rw-r--r-- | pysc-v/Frontend/__init__.py | 0 | ||||
-rw-r--r-- | pysc-v/Frontend/lexer.py | 4 | ||||
-rw-r--r-- | pysc-v/Frontend/reader.py (renamed from reader.py) | 0 | ||||
-rw-r--r-- | pysc-v/InstructionSets/RV32C.py | 29 | ||||
-rw-r--r-- | pysc-v/InstructionSets/RV32D.py | 0 | ||||
-rw-r--r-- | pysc-v/InstructionSets/RV32F.py | 0 | ||||
-rw-r--r-- | pysc-v/InstructionSets/RV32I.py | 71 | ||||
-rw-r--r-- | pysc-v/InstructionSets/__init__.py | 0 | ||||
-rw-r--r-- | pysc-v/InstructionSets/instructions.py | 30 | ||||
-rw-r--r-- | pysc-v/main.py | 5 | ||||
-rw-r--r-- | pysc-v/memory.py (renamed from memory.py) | 0 | ||||
-rw-r--r-- | pysc-v/registers/RV32I.py (renamed from registersRV32I.py) | 0 | ||||
-rw-r--r-- | pysc-v/registers/__init__.py | 0 |
15 files changed, 140 insertions, 145 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/instructions.py b/instructions.py deleted file mode 100644 index 0bfda4c..0000000 --- a/instructions.py +++ /dev/null @@ -1,145 +0,0 @@ -# Full list of instructions -""" -U lui -U auipc -J jal -I jalr -B beq -B bne -B blt -B bge -B bltu -B bgeu -I lb -I lh -I lw -I lbu -I lhu -S sb -S sh -S sw -I addi -I slti -I sltiu -I xori -I ori -I andi -I slli -I srli -I srai -R add -R sub -R sll -R slt -R sltu -R xor -R srl -R sra -R or -R and -I fence -I fence.i -I ecall -I ebreak -I csrrw -I csrrs -I csrrc -I csrrwi -I csrrsi -I csrrci -""" - - -from ctypes import c_uint32 - -class Instruction: - - self.memory = None - self.regs = None - - def __init__(self): - pass - - def compile(self): - # return the binstream of the instruction in a c_uint32 - pass - - def execute(self): - # executes the instruction and returns the next program counter - return - -class R(Instruction): - funct3 = None - funct7 = None - opcode = None - def __init__(self, rd, rs1, rs2): - self.rd = rd - self.rs1 = rs1 - self.rs2 = rs2 - - def compile(self): - # TODO: ensure sizes and convert register names to number... - return c_uint32( - (self.funct7 << 25) +\ - (self.rs2 << 20) +\ - (self.rs1 << 15) +\ - (self.funct3 << 12) +\ - (self.rd << 7) +\ - self.opcode - ) - -class I(Instruction): - funct3 = None - opcode = None - - def __init__(self, rd, rs, imm): - self.rd = rd - self.rs = rs - self.imm = imm - - def compile(self): - return c_uint32( - (self.imm << 20) +\ - (self.rs << 15) +\ - (self.funct3 << 12) +\ - (self.rd << 7) +\ - self.opcode - ) - -class S(Instruction): - pass - -class B(Instruction): - pass - -class U(Instruction): - pass - -class J(Instruction): - pass - - - -class add(R): - name = "add" - opcode = 0b0110011 - funct3 = 0b000 - funct7 = 0b0000000 - - def execute(self): - pass - - -class addi(I): - name = "addi" - opcode = 0b0010011 - funct3 = 0b000 - - def execute(self): - pass - -if __name__ == "__main__": - r = Regs() - # This is the interface i'd love to have - addins = add("x5","x2","zero") - j("labelName") diff --git a/pysc-v/Frontend/__init__.py b/pysc-v/Frontend/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysc-v/Frontend/__init__.py diff --git a/pysc-v/Frontend/lexer.py b/pysc-v/Frontend/lexer.py new file mode 100644 index 0000000..5175097 --- /dev/null +++ b/pysc-v/Frontend/lexer.py @@ -0,0 +1,4 @@ +# Returns: +# - label +# - instruction (with args) +# - directive (with args) diff --git a/reader.py b/pysc-v/Frontend/reader.py index 45d155c..45d155c 100644 --- a/reader.py +++ b/pysc-v/Frontend/reader.py diff --git a/pysc-v/InstructionSets/RV32C.py b/pysc-v/InstructionSets/RV32C.py new file mode 100644 index 0000000..e740ac4 --- /dev/null +++ b/pysc-v/InstructionSets/RV32C.py @@ -0,0 +1,29 @@ +from instructions import Instruction, InstructionSet + +class Compressed(Instruction): + size = 2 + + +class CR(Compressed): + pass + +class CI(Compressed): + pass + +class CSS(Compressed): + pass + +class CIW(Compressed): + pass + +class CJ(Compressed): + pass + +class CB(Compressed): + pass + +class CL(Compressed): + pass + +class CS(Compressed): + pass diff --git a/pysc-v/InstructionSets/RV32D.py b/pysc-v/InstructionSets/RV32D.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysc-v/InstructionSets/RV32D.py diff --git a/pysc-v/InstructionSets/RV32F.py b/pysc-v/InstructionSets/RV32F.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysc-v/InstructionSets/RV32F.py diff --git a/pysc-v/InstructionSets/RV32I.py b/pysc-v/InstructionSets/RV32I.py new file mode 100644 index 0000000..967b24d --- /dev/null +++ b/pysc-v/InstructionSets/RV32I.py @@ -0,0 +1,71 @@ +from instructions import Instruction, InstructionSet + +RV32I = InstructionSet() + +class R(Instruction): + funct3 = None + funct7 = None + opcode = None + def __init__(self, rd, rs1, rs2): + self.rd = rd + self.rs1 = rs1 + self.rs2 = rs2 + + def compile(self): + # TODO: ensure sizes and convert register names to number... + return c_uint32( + (self.funct7 << 25) +\ + (self.rs2 << 20) +\ + (self.rs1 << 15) +\ + (self.funct3 << 12) +\ + (self.rd << 7) +\ + self.opcode + ) + +class I(Instruction): + funct3 = None + opcode = None + + def __init__(self, rd, rs, imm): + self.rd = rd + self.rs = rs + self.imm = imm + + def compile(self): + return c_uint32( + (self.imm << 20) +\ + (self.rs << 15) +\ + (self.funct3 << 12) +\ + (self.rd << 7) +\ + self.opcode + ) + +class S(Instruction): + pass + +class B(Instruction): + pass + +class U(Instruction): + pass + +class J(Instruction): + pass + + +class add(R): + name = "add" + opcode = 0b0110011 + funct3 = 0b000 + funct7 = 0b0000000 + + def execute(self): + return pc + self.size + +class addi(I): + name = "addi" + opcode = 0b0010011 + funct3 = 0b000 + + def execute(self): + pass diff --git a/pysc-v/InstructionSets/__init__.py b/pysc-v/InstructionSets/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysc-v/InstructionSets/__init__.py diff --git a/pysc-v/InstructionSets/instructions.py b/pysc-v/InstructionSets/instructions.py new file mode 100644 index 0000000..5587f2e --- /dev/null +++ b/pysc-v/InstructionSets/instructions.py @@ -0,0 +1,30 @@ +from ctypes import c_uint32 + + +class Instruction: + size = 4 # Instruction size in bytes + + def __init__(self): + pass + + def compile(self): + # return the binstream of the instruction in a c_uint32 + pass + + def execute(self): + # executes the instruction and returns the next program counter + return + +class InstructionSet: + def __init__(self, init=None): + self.data = dict() + + def add_instruction(self, ins): + if ins.name not in self.data: + self.data[ins.name] = ins + + +if __name__ == "__main__": + # TODO This is the interface i'd love to have + addins = add("x5","x2","zero") + j("labelName") diff --git a/pysc-v/main.py b/pysc-v/main.py new file mode 100644 index 0000000..2d6f6a5 --- /dev/null +++ b/pysc-v/main.py @@ -0,0 +1,5 @@ +# Use a generator for the execution flow +# -> PC has to be a global variable, updated by each instruction to the next val +# So user can set the PC by hand and call next(run) and make the code jump! + + diff --git a/memory.py b/pysc-v/memory.py index 84bf0bd..84bf0bd 100644 --- a/memory.py +++ b/pysc-v/memory.py diff --git a/registersRV32I.py b/pysc-v/registers/RV32I.py index 4652bca..4652bca 100644 --- a/registersRV32I.py +++ b/pysc-v/registers/RV32I.py diff --git a/pysc-v/registers/__init__.py b/pysc-v/registers/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/pysc-v/registers/__init__.py |