代码拉取完成,页面将自动刷新
from register_file import *
from data_type import *
def sign_expend(x, len):
if x & (1 << len - 1):
return x - (1 << len)
else:
return x
def mask(n):
return (1 << n) - 1
def get_bit(x, L, R):
return x >> R & mask(L - R + 1)
class type:
def __init__(self):
self.name = ""
self.float = False
self.size = 0 # 0 -> dw, 1 -> w, 2 -> h, 3 -> b, 4 -> s.d, 5 -> d.wu, 6 -> wu.d, 7 -> l.d, 8 ->d.l,
# 9 -> w.d, 10 -> d.w, 11 -> d.x, 12 -> x.d
self.do = 0 # 0 -> reg, 1 -> save, 2 -> load, 3 -> branch
self.imm = False
self.unsigned = False
self.wb = False
self.stack = False
def decoder_16(instr):
job = type()
rs1 = 0
rs2 = 0
rd = 0
imm = 0
job.imm = False
opcode = instr & 0b11
if opcode == 0b01:
funct3 = (instr >> 13) & 0b111
idx_12 = (instr >> 12) & 0b1
idx_117 = (instr >> 7) & 0b11111
idx_62 = (instr >> 2) & 0b11111
idx_1210 = (instr >> 10) & 0b111
idx_97 = (instr >> 7) & 0b111
if funct3 == 0b000:
if idx_117 == 0:
job.name = "" # nop
job.do = 4
else:
job.name = "add" # addi
job.imm = True
rs1 = rd = idx_117
imm_pre = (idx_12 << 5) | idx_62
imm = sign_expend(imm_pre, 6)
elif funct3 == 0b001:
job.name = "add" # addiw
job.size = 1
job.imm = True
rs1 = rd = idx_117
imm_pre = (idx_12 << 5) | idx_62
imm = sign_expend(imm_pre, 6)
elif funct3 == 0b010:
job.name = "add" # li
job.imm = True
rd = idx_117
rs1 = 0
imm_pre = (idx_12 << 5) | idx_62
imm = sign_expend(imm_pre, 6)
elif funct3 == 0b011:
if idx_117 == 2:
job.name = "add" # addi16sp
job.imm = True
rd = rs1 = 2
imm_pre = (idx_12 << 9) | (get_bit(idx_62, 2, 1) << 7) | (get_bit(idx_62, 3, 3) << 6) | (
get_bit(idx_62, 0, 0) << 5) | (get_bit(idx_62, 4, 4) << 4)
imm = sign_expend(imm_pre, 10)
else:
job.name = "lui"
job.imm = True
job.do = 4
rd = idx_117
imm_pre = (idx_12 << 17) | (idx_62 << 12)
imm = sign_expend(imm_pre, 18)
elif funct3 == 0b100:
idx_1110 = (instr >> 10) & 0b11
if idx_1110 == 0b00:
job.name = "srl" # srl
job.imm = True
rs1 = rd = idx_97 + 8
imm_pre = (idx_12 << 5) | idx_62
imm = imm_pre
elif idx_1110 == 0b01:
job.name = "sra" # srai
job.imm = True
rs1 = rd = idx_97 + 8
imm_pre = (idx_12 << 5) | idx_62
imm = imm_pre
elif idx_1110 == 0b10:
job.name = "and" # andi
job.imm = True
rs1 = rd = idx_97 + 8
imm_pre = (idx_12 << 5) | idx_62
imm = sign_expend(imm_pre, 6)
else:
idx_65 = (instr >> 5) & 0b11
idx_42 = (instr >> 2) & 0b111
if idx_12 == 1:
if idx_65 == 0b01:
job.name = "add" # addw
job.size = 1
rd = rs1 = idx_97 + 8
rs2 = idx_42 + 8
elif idx_65 == 0b00:
job.name = "sub" # subw
job.size = 1
rd = rs1 = idx_97 + 8
rs2 = idx_42 + 8
elif idx_65 == 0b00:
job.name = "sub"
rs1 = rd = idx_97 + 8
rs2 = idx_42 + 8
elif idx_65 == 0b01:
job.name = "xor"
rs1 = rd = idx_97 + 8
rs2 = idx_42 + 8
elif idx_65 == 0b10:
job.name = "or"
rs1 = rd = idx_97 + 8
rs2 = idx_42 + 8
else:
job.name = "and"
rs1 = rd = idx_97 + 8
rs2 = idx_42 + 8
elif funct3 == 0b101:
job.name = "jal" # j
job.do = 3
job.imm = True
rd = 0
temp = (instr >> 2) & 0b11111111111
imm_pre = (get_bit(temp, 10, 10) << 11) | (get_bit(temp, 6, 6) << 10) | (get_bit(temp, 8, 7) << 8) | (
get_bit(temp, 4, 4) << 7) | (get_bit(temp, 5, 5) << 6) | (get_bit(temp, 0, 0) << 5) | (
get_bit(temp, 9, 9) << 4) | (get_bit(temp, 3, 1) << 1)
imm = sign_expend(imm_pre, 12)
elif funct3 == 0b110:
job.name = "beq" # beqz
job.do = 3
job.imm = True
rs1 = idx_97 + 8
rs2 = 0
imm_pre = (get_bit(idx_1210, 2, 2) << 8) | (get_bit(idx_62, 4, 3) << 6) | (get_bit(idx_62, 0, 0) << 5) | (
get_bit(idx_1210, 1, 0) << 3) | (get_bit(idx_62, 2, 1) << 1)
imm = sign_expend(imm_pre, 9)
else:
job.name = "bne" # bnez
job.do = 3
job.imm = True
rs1 = idx_97 + 8
rs2 = 0
imm_pre = (get_bit(idx_1210, 2, 2) << 8) | (get_bit(idx_62, 4, 3) << 6) | (get_bit(idx_62, 0, 0) << 5) | (
get_bit(idx_1210, 1, 0) << 3) | (get_bit(idx_62, 2, 1) << 1)
imm = sign_expend(imm_pre, 9)
elif opcode == 0b00:
funct3 = (instr >> 13) & 0b111
idx_42 = (instr >> 2) & 0b111
idx_1210 = (instr >> 10) & 0b111
idx_97 = (instr >> 7) & 0b111
idx_65 = (instr >> 5) & 0b11
if funct3 == 0b000:
idx_125 = (instr >> 5) & 0xff
if idx_125 == 0:
job.name = 'illegal'
job.do = 4
else:
job.name = "add" # add
job.imm = True
rd = idx_42 + 8
rs1 = 2
uimm_pre = (get_bit(idx_125, 5, 2) << 6) | (get_bit(idx_125, 7, 6) << 4) | (
get_bit(idx_125, 0, 0) << 3) | (get_bit(idx_125, 1, 1) << 2)
imm = uimm_pre
elif funct3 == 0b001:
job.name = "fld"
job.imm = True
job.do = 2
job.float = True
rs1 = idx_97 + 8
if rs1 == 2:
job.stack = True
rd = idx_42 + 8
uimm_pre = (idx_65 << 6) | (idx_1210 << 3)
imm = uimm_pre
elif funct3 == 0b010:
job.name = "lw"
job.imm = True
job.do = 2
job.size = 1
rs1 = idx_97 + 8
if rs1 == 2:
job.stack = True
rd = idx_42 + 8
uimm_pre = (get_bit(idx_65, 0, 0) << 6) | (idx_1210 << 3) | (get_bit(idx_65, 1, 1) << 2)
imm = uimm_pre
elif funct3 == 0b011:
job.name = "ld"
job.imm = True
job.do = 2
rs1 = idx_97 + 8
if rs1 == 2:
job.stack = True
rd = idx_42 + 8
uimm_pre = (idx_65 << 6) | (idx_1210 << 3)
imm = uimm_pre
elif funct3 == 0b101:
job.name = "fsd"
job.imm = True
job.float = True
job.do = 1
rs1 = idx_97 + 8
rs2 = idx_42 + 8
uimm_pre = (idx_65 << 6) | (idx_1210 << 3)
imm = uimm_pre
elif funct3 == 0b110:
job.name = "sw"
job.imm = True
job.do = 1
job.size = 1
rs1 = idx_97 + 8
rs2 = idx_42 + 8
if rs1 == 2:
job.stack = True
uimm_pre = (get_bit(idx_65, 0, 0) << 6) | (idx_1210 << 3) | (get_bit(idx_65, 1, 1) << 2)
imm = uimm_pre
elif funct3 == 0b111:
job.name = "sd"
job.do = 1
rs1 = idx_97 + 8
if rs1 == 2:
job.stack = True
rs2 = idx_42 + 8
uimm_pre = (idx_65 << 6) | (idx_1210 << 3)
imm = uimm_pre
elif opcode == 0b10:
funct3 = (instr >> 13) & 0b111
idx_117 = (instr >> 7) & 0b11111
idx_12 = (instr >> 12) & 0b1
idx_62 = (instr >> 2) & 0b11111
idx_127 = (instr >> 7) & 0b111111
if funct3 == 0b000:
job.name = "sll" # slli
job.imm = True
rs1 = rd = idx_117
uimm_pre = (idx_12 << 5) | idx_62
imm = uimm_pre
elif funct3 == 0b001:
job.name = "fld" # fldsp ==============================================
job.imm = True
job.float = True
job.do = 2
rd = idx_117
rs1 = 2
job.stack = True
uimm_pre = (get_bit(idx_62, 2, 0) << 6) | (idx_12 << 5) | (get_bit(idx_62, 4, 3) << 3)
imm = uimm_pre
elif funct3 == 0b010:
job.name = "lw" # lwsp ================================================
job.imm = True
job.do = 2
job.size = 1
rd = idx_117
rs1 = 2
job.stack = True
uimm_pre = (get_bit(idx_62, 2, 0) << 6) | (idx_12 << 5) | (get_bit(idx_62, 4, 3) << 2)
imm = uimm_pre
elif funct3 == 0b011:
job.name = "ld" # ldsp ================================================
job.imm = True
job.do = 2
rd = idx_117
rs1 = 2
job.stack = True
uimm_pre = (get_bit(idx_62, 2, 0) << 6) | (idx_12 << 5) | (get_bit(idx_62, 4, 3) << 3)
imm = uimm_pre
elif funct3 == 0b100:
if not idx_12:
if idx_62 == 0:
job.name = "jalr" # jr
job.imm = False
job.do = 3
rs1 = idx_117
rd = 0
else:
job.name = "add" # mv =========================================
job.imm = False
rd = idx_117
rs1 = 0
rs2 = idx_62
else:
if idx_62 == 0:
job.name = "jalr"
job.imm = False
job.do = 3
rs1 = idx_117
rd = 1
else:
job.name = "add"
job.imm = False
rd = rs1 = idx_117
rs2 = idx_62
elif funct3 == 0b101:
job.name = "fsd" # fsdsp ==============================================
job.imm = True
job.do = 1
job.float = True
rs1 = 2
job.stack = True
rs2 = idx_62
uimm_pre = (get_bit(idx_127, 2, 0) << 6) | (get_bit(idx_127, 5, 3) << 3)
imm = uimm_pre
elif funct3 == 0b110:
job.name = "sw" # swsp ================================================
job.imm = True
job.do = 1
job.size = 1
rs1 = 2
job.stack = True
rs2 = idx_62
uimm_pre = (get_bit(idx_127, 1, 0) << 6) | (get_bit(idx_127, 5, 2) << 2)
imm = uimm_pre
elif funct3 == 0b111:
job.name = "sd" # sdsp ================================================
job.imm = True
job.do = 1
rs1 = 2
job.stack = True
rs2 = idx_62
uimm_pre = (get_bit(idx_127, 2, 0) << 6) | (get_bit(idx_127, 5, 3) << 3)
imm = uimm_pre
return job, rs1, rs2, rd, imm
I = (0b0010011, 0b0000011, 0b1100111, 0b1110011, 0b0000111, 0b0011011)
def decoder_32(instr):
job = type()
rs1 = 0
rs2 = 0
rd = 0
imm = 0
job.imm = False
opcode = instr & 0b1111111
if opcode == 0b0110011: # R-type
funct7 = get_bit(instr, 31, 25)
funct3 = get_bit(instr, 14, 12)
rs2 = get_bit(instr, 24, 20)
rs1 = get_bit(instr, 19, 15)
rd = get_bit(instr, 11, 7)
if funct3 == 0b000:
if funct7 == 0x00:
job.name = "add"
elif funct7 == 0x01:
job.name = "mul"
elif funct7 == 0x20:
job.name = "sub"
elif funct3 == 0b001:
job.name = "sll"
elif funct3 == 0b010:
job.name = "slt"
elif funct3 == 0b011:
if funct7 == 0x00:
job.name = "slt" # sltu
job.unsigned = True
elif funct7 == 0x01:
job.name = "mulh" # mulhu
job.unsigned = True
elif funct3 == 0b100:
job.name = "xor"
elif funct3 == 0b101:
if funct7 == 0x00:
job.name = "srl"
elif funct7 == 0x01:
job.name = "div" # divu
job.unsigned = True
elif funct7 == 0x20:
job.name = "sra"
elif funct3 == 0b110:
job.name = "or"
elif funct3 == 0b111:
if funct7 == 0x00:
job.name = "and"
elif funct7 == 0x01:
job.name = "rem" # remu
job.unsigned = True
elif opcode == 0b1010011:
rs2 = get_bit(instr, 24, 20)
rs1 = get_bit(instr, 19, 15)
rd = get_bit(instr, 11, 7)
funct3 = get_bit(instr, 14, 12)
funct5 = get_bit(instr, 31, 27)
fmt = get_bit(instr, 26, 25)
if funct5 == 0b00000:
if fmt == 0b00:
job.name = "fadd.s"
job.float = True
job.size = 1
elif fmt == 0b01:
job.name = "fadd.d"
job.float = True
elif funct5 == 0b00001:
if fmt == 0b00:
job.name = "fsub.s"
job.float = True
job.size = 1
elif fmt == 0b01:
job.name = "fsub.d"
job.float = True
elif funct5 == 0b00010:
if fmt == 0b00:
job.name = "fmul.s"
job.float = True
job.size = 1
elif fmt == 0b01:
job.name = "fmul.d"
job.float = True
elif funct5 == 0b00011:
if fmt == 0b00:
job.name = "fdiv.s"
job.float = True
job.size = 1
elif fmt == 0b01:
job.name = "fdiv.d"
job.float = True
elif funct5 == 0b11010:
if rs2 == 0b00010:
job.name = "fcvt.d.l"
job.size = 8
elif rs2 == 0b00000:
job.name = "fcvt.d.w"
job.size = 10
elif rs2 == 0b00001:
job.name = "fcvt.d.wu"
job.size = 5
elif funct5 == 0b11000:
if rs2 == 0b00000:
job.name = "fcvt.w.d"
elif rs2 == 0b00001:
job.name = "fcvt.wu.d"
elif rs2 == 0b00010:
job.name = "fcvt.l.d"
elif funct5 == 0b01000:
if rs2 == 0b00001:
job.name = "fcvt.s.d"
elif funct5 == 0b11110: # 还有.w.x跟fmt有关
job.name = "fmv.d.x"
elif funct5 == 0b11100:
job.name = "fmv.x.d"
elif funct5 == 0b00100:
if funct3 == 0b000:
if fmt == 0b01:
job.name = "fsgnj.d"
elif fmt == 0b00:
job.name = "fsgnj.s"
elif funct3 == 0b001:
if fmt == 0b01:
job.name = "fsgnjn.d"
elif fmt == 0b00:
job.name = "fsgnjn.s"
elif funct3 == 0b010:
if fmt == 0b01:
job.name = "fsgnjx.d"
elif fmt == 0b00:
job.name = "fsgnjx.s"
elif funct5 == 0b10100:
if funct3 == 0b010:
if fmt == 0b01:
job.name = "feq.d"
elif fmt == 0b00:
job.name = "feq.s"
elif funct3 == 0b001:
if fmt == 0b01:
job.name = "flt.d"
elif fmt == 0b00:
job.name = "flt.s"
elif funct3 == 0b000:
if fmt == 0b01:
job.name = "fle.d"
elif fmt == 0b00:
job.name = "fle.s"
elif opcode == 0b1000011:
rs2 = get_bit(instr, 24, 20)
rs1 = get_bit(instr, 19, 15)
rs3 = get_bit(instr, 31, 27)
rd = get_bit(instr, 11, 7)
fmt = get_bit(instr, 26, 25)
if fmt == 0b01:
job.name = "fmadd.d"
elif fmt == 0b00:
job.name = "fmadd.s"
elif opcode == 0b0111011:
rs1 = get_bit(instr, 19, 15)
rs2 = get_bit(instr, 24, 20)
rd = get_bit(instr, 11, 7)
funct3 = get_bit(instr, 14, 12)
funct7 = get_bit(instr, 31, 25)
if funct7 == 0b0000001:
if funct3 == 0b000:
job.name = "mul" # mulw
job.size = 1
elif funct3 == 0b100: # divw
job.name = "div"
job.size = 1
elif funct3 == 0b110:
job.name = "rem" # remw
job.size = 1
else:
if funct3 == 0b000:
if funct7 == 0x00:
job.name = "add" # addw
job.size = 1
elif funct7 == 0x20:
job.name = "sub" # subw
job.size = 1
elif funct3 == 0b001:
job.name = "sll" # sllw
job.size = 1
elif funct3 == 0b101:
if funct7 == 0x00:
job.name = "srl" # srlw
job.size = 1
elif funct7 == 0x20:
job.name = "sra" # sraw
job.size = 1
elif opcode in I: # I-type
imm_pre = (get_bit(instr, 31, 20))
imm = sign_expend(imm_pre, 12)
rs1 = get_bit(instr, 19, 15)
funct3 = get_bit(instr, 14, 12)
rd = get_bit(instr, 11, 7)
job.imm = True
funct6 = get_bit(instr, 31, 26)
shamt = get_bit(instr, 25, 20)
if opcode == 0b0010011:
if funct3 == 0b000:
job.name = "add" # addi
elif funct3 == 0b010:
job.name = "slt" # slti
elif funct3 == 0b011:
job.name = "slt" # sltiu
job.unsigned = True
imm = imm_pre
elif funct3 == 0b100:
job.name = "xor" # xori
elif funct3 == 0b110:
job.name = "or" # ori
elif funct3 == 0b111:
job.name = "and" # andi
elif funct3 == 0b001:
job.name = "sll" # slli
imm = shamt
elif funct3 == 0b101:
if funct6 == 0x00:
job.name = "srl" # srli
imm = shamt
elif funct6 == 0x10:
job.name = "sra" # srai
imm = shamt
elif opcode == 0b0000011:
if funct3 == 0b000:
job.name = "lb"
job.do = 2
job.size = 3
if rs1 == 2:
job.stack = True
elif funct3 == 0b001:
job.name = "lh"
job.do = 2
job.size = 2
if rs1 == 2:
job.stack = True
elif funct3 == 0b010:
job.name = "lw"
job.do = 2
job.size = 1
if rs1 == 2:
job.stack = True
elif funct3 == 0b011:
job.name = "ld"
job.do = 2
if rs1 == 2:
job.stack = True
elif funct3 == 0b100:
job.name = "lbu"
job.do = 2
job.size = 3
job.unsigned = True
if rs1 == 2:
job.stack = True
imm = imm_pre
elif funct3 == 0b101:
job.name = "lhu"
job.do = 2
job.size = 2
job.unsigned = True
if rs1 == 2:
job.stack = True
imm = imm_pre
elif funct3 == 0b110:
job.name = "lwu"
job.do = 2
job.size = 1
job.unsigned = True
if rs1 == 2:
job.stack = True
imm = imm_pre
elif opcode == 0b1100111:
job.name = "jalr"
job.do = 3
elif opcode == 0b1110011:
if funct3 == 0b000:
job.name = "ecall"
job.do = 4
elif funct3 == 0b001:
job.name = "csrrw"
job.do = 4
elif funct3 == 0b010:
job.name = "csrrs"
job.do = 4
elif funct3 == 0b110:
job.name = "cssrrsi"
job.do = 4
elif opcode == 0b0000111:
if funct3 == 0b010:
job.name = "flw"
elif funct3 == 0b011:
job.name = "fld"
elif opcode == 0b0011011:
if funct3 == 0b000:
job.name = "add" # addiw
job.size = 1
elif funct3 == 0b001:
job.name = "sll" # slliw
job.size = 1
imm = shamt
elif funct3 == 0b101:
if funct6 == 0x00:
job.name = "srl" # srliw
job.size = 1
imm = shamt
elif funct6 == 0x10:
job.name = "sra" # sraiw
job.size = 1
imm = shamt
elif opcode == 0b0110111: # U-type
job.name = "lui"
job.imm = True
job.do = 4
rd = get_bit(instr, 11, 7)
imm = get_bit(instr, 31, 12) << 12
elif opcode == 0b0010111:
job.name = "auipc"
job.imm = True
job.do = 4
rd = get_bit(instr, 11, 7)
imm = get_bit(instr, 31, 12) << 12
elif opcode == 0b1101111: # J-type
job.name = "jal"
job.imm = True
job.do = 3
idx_3112 = get_bit(instr, 31, 12)
imm_pre = (get_bit(idx_3112, 19, 19) << 20) | (get_bit(idx_3112, 7, 0) << 12) | (
get_bit(idx_3112, 8, 8) << 11) | (get_bit(idx_3112, 18, 9) << 1)
imm = sign_expend(imm_pre, 21)
rd = get_bit(instr, 11, 7)
elif opcode == 0b0100011: # S-type
imm_pre = (get_bit(instr, 31, 25) << 5) | get_bit(instr, 11, 7)
imm = sign_expend(imm_pre, 12)
job.imm = True
rs2 = get_bit(instr, 24, 20)
rs1 = get_bit(instr, 19, 15)
funct3 = get_bit(instr, 14, 12)
if funct3 == 0b000:
job.name = "sb"
job.do = 1
job.size = 3
if rs1 == 2:
job.stack = True
elif funct3 == 0b001:
job.name = "sh"
job.do = 1
job.size = 2
if rs1 == 2:
job.stack = True
elif funct3 == 0b010:
job.name = "sw"
job.do = 1
job.size = 1
if rs1 == 2:
job.stack = True
elif funct3 == 0b011:
job.name = "sd"
job.do = 1
if rs1 == 2:
job.stack = True
elif opcode == 0b0100111:
imm_pre = (get_bit(instr, 31, 25) << 5) | get_bit(instr, 11, 7)
imm = sign_expend(imm_pre, 12)
job.imm = True
rs2 = get_bit(instr, 24, 20)
rs1 = get_bit(instr, 19, 15)
funct3 = get_bit(instr, 14, 12)
if funct3 == 0b010:
job.name = "fsw"
elif funct3 == 0b011:
job.name = "fsd"
elif opcode == 0b1100011: # B-type
rs2 = get_bit(instr, 24, 20)
rs1 = get_bit(instr, 19, 15)
funct3 = get_bit(instr, 14, 12)
idx_3125 = get_bit(instr, 31, 25)
idx_117 = get_bit(instr, 11, 7)
imm_pre = (get_bit(idx_3125, 6, 6) << 12) | (get_bit(idx_117, 0, 0) << 11) | (get_bit(idx_3125, 5, 0) << 5) | (
get_bit(idx_117, 4, 1) << 1)
imm = sign_expend(imm_pre, 13)
job.imm = True
if funct3 == 0b000:
job.name = "beq"
job.do = 3
elif funct3 == 0b001:
job.name = "bne"
job.do = 3
elif funct3 == 0b100:
job.name = "blt"
job.do = 3
elif funct3 == 0b101:
job.name = "bge"
job.do = 3
elif funct3 == 0b110:
job.name = "blt" # bltu
job.do = 3
job.unsigned = True
elif funct3 == 0b111:
job.name = "bge" # bgeu
job.do = 3
job.unsigned = True
return job, rs1, rs2, rd, imm
def ID(instr, width, pc: bit_64, rf: registers_file):
if width == 16:
job, rs1, rs2, rd, imm = decoder_16(instr)
else:
job, rs1, rs2, rd, imm = decoder_32(instr)
rs1_r, rs2_r = rf.ports_out(rs1, rs2)
# print("ID: %s x%d, x%d, x%d %d" % (job.name, rd, rs1, rs2, imm))
return job, bit_64(rs1_r), bit_64(rs2_r), bit_64(imm), rs1, rs2, rd, pc, width
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。