An RV32IMF implementation w/ migen/LiteX
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Risq5/debugger/dbgeval.py

301 lines
14 KiB

#!/usr/bin/env python3
#
# dbgeval.py
# Diverse stati strings
#
x_description = [ # Pseudo reg. naming ...
" ze", " ra", " sp", " gp", " tp", " t0", " t1", " t2",
" fp", " s1", " a0", " a1", " a2", " a3", " a4", " a5",
" a6", " a7", " s2", " s3", " s4", " s5", " s6", " s7",
" s8", " s9", " s10", " s11", " t3", " t4", " t5", " t6"
]
csr_description = {
0x300 : "mstatus",
0x344 : "mip",
0x304 : "mie",
0x342 : "mcause",
0x305 : "mtvec",
0x343 : "mtval",
0x341 : "mepc",
0x340 : "mscratch",
0x301 : "misa",
0xF11 : "mvendorid",
0xF12 : "marchid",
0xF13 : "mimpid",
0xF14 : "mhartid"
}
def flag(val, c1, c2):
if val != 0:
return c1
return c2
def disassemble(opcode, pc):
"""Build disassembly instruction from opcode & w/ current PC"""
op = opcode & 0x7F # [ 0: 6]
rd = (opcode >> 7) & 0x1F # [ 7:11]
f3 = (opcode >> 12) & 0x7 # [12:14]
rs1 = (opcode >> 15) & 0x1F # [15:19]
rs2 = (opcode >> 20) & 0x1F # [20:14]
f7 = (opcode >> 25) # [25:31]
imm_i = (opcode >> 20); # [20:31]
imm_s = rd | (f7 << 5);
imm_b = (
((opcode >> 8) & 0xF) # [04:01]4 (8:11) OK
| ((opcode & 0x7E000000) >> (25-4)) # [10:05]6 (25:30)
| ((opcode & 0x80) << (10-7)) # [11]1 (7)
| ((opcode & 0x80000000) >> (31-11)) # [12]1 (31) (sign)
) << 1 # [0] added
if (opcode & 0x80000000) != 0:
imm_b = imm_b | 0xFFFFF000 # Sign extend
imm_u = (opcode >> 12)
# J-type immediate (19 bits << 1 )
# op[21..30] 10bit -> imm[1..10]
# op[20] 1bit -> imm[11]
# op[12..19] 8bit -> imm[12..19]
# op[31] 1bit -> imm[20]
imm_j = (
((opcode >> 21) & 0x3FF) # 0..9
| (((opcode >> 20) & 1) << 10) # 10
| (((opcode >> 12) & 0xFF) << 11) # 11..18
| ((opcode & 0x80000000) >> (31-12)) # 19
) << 1
if (opcode & 0x80000000) != 0:
imm_j = imm_j | 0xFFF00000 # Sign extend
try:
msg = "-- still unknown? --"
if op == 0x37:
msg = "lui {0},{1}".format(x_description[rd], hex(imm_u))
elif op == 0x17:
msg = "auipc {0},{1}".format(x_description[rd], hex(imm_u))
elif op == 0x33: # R-Type
if f3 == 0x00: # add/sub
if f7 == 0x00: # add
msg = "add {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x20: # sub
msg = "sub {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mul
msg = "mul {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x01:
if f7 == 0x00: # sll
msg = "sll {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mulh
msg = "mulh {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x02:
if f7 == 0x00: # slt
msg = "slt {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mulhsu
msg = "mulhsu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x03:
if f7 == 0x00: # sltu
msg = "sltu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f7 == 0x01: # mulhu
msg = "mulhu {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x04:
msg = "xor {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x05:
if f7 == 0x20:
msg = "sra {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
else:
msg = "srl {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x06:
msg = "or {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif f3 == 0x07:
if f7 == 0x00: # and rd, rs1, rs2
msg = "and {0},{1},{2}".format(x_description[rd], x_description[rs1], x_description[rs2])
elif op == 0x63:
if f3 == 0x00:
msg = "beq {0},{1},{2}".format(x_description[rs1], x_description[rs2], hex((pc+imm_b) & 0xFFFFFFFF))
if f3 == 0x05:
msg = "bge {0},{1},{2}".format(x_description[rs1], x_description[rs2], hex((pc+imm_b) & 0xFFFFFFFF))
if f3 == 0x07:
msg = "bgeu {0},{1},{2}".format(x_description[rs1], x_description[rs2], hex((pc+imm_b) & 0xFFFFFFFF))
if f3 == 0x04:
msg = "blt {0},{1},{2}".format(x_description[rs1], x_description[rs2], hex((pc+imm_b) & 0xFFFFFFFF))
if f3 == 0x06:
msg = "bltu {0},{1},{2}".format(x_description[rs1], x_description[rs2], hex((pc+imm_b) & 0xFFFFFFFF))
if f3 == 0x01:
msg = "bne {0},{1},{2}".format(x_description[rs1], x_description[rs2], hex((pc+imm_b) & 0xFFFFFFFF))
elif op == 0x6F: # J-Type (jal)
msg = "jal {0},{1}".format(x_description[rd], hex((pc+imm_j) & 0xFFFFFFFF))
elif op == 0x67: # I-Type (jalr)
if opcode == 0x00008067: # Special case: ret
msg = "ret ( jalr {0},{1}({2}) )".format(x_description[rd], hex(imm_i & 0xFFFFFFFF), x_description[rs1])
elif f3 == 0x00:
msg = "jalr {0},{1}({2})".format(x_description[rd], hex(imm_i & 0xFFFFFFFF), x_description[rs1])
elif op == 0x73:
try:
csrname = csr_description[imm_i]
except:
csrname = "csr?{0}".format(hex(imm_i))
if f3 != 0x00: # Ignore special cases (s.b.)
print("Special CSR detected: {0}".format(csrname))
if f3 == 0x03: # csrrc rd, csr, rs1 (csr read & clear)
msg = "csrrc {0},{1},{2}".format(x_description[rd], csrname, x_description[rs1])
elif f3 == 0x07: # csrrci rd, csr, imm_i4 (csr read & clear immediate)
msg = "csrrci {0},{1},{2}".format(x_description[rd], csrname, hex(rs1))
elif f3 == 0x02: # csrrs rd, csr, rs1 (csr read & set)
msg = "csrrs {0},{1},{2}".format(x_description[rd], csrname, x_description[rs1])
elif f3 == 0x06: # csrrsi rd, csr, imm_i4 (csr read & set immediate)
msg = "csrrsi {0},{1},{2}".format(x_description[rd], csrname, hex(rs1))
elif f3 == 0x01: # csrrw rd, csr, rs1 (csr read & write)
msg = "csrrw {0},{1},{2}".format(x_description[rd], csrname, x_description[rs1])
elif f3 == 0x05: # csrrwi rd, csr, imm_i4 (csr read & write immediate)
msg = "csrrwi {0},{1},{2}".format(x_description[rd], csrname, hex(rs1))
elif f3 == 0x00: # exception handling
if opcode == 0x30200073:
msg = "mret"
elif opcode == 0x00100073:
msg = "ebreak"
else: # Raise exception
msg = "ecall"
elif op == 0x23:
if f3 == 0x00:
msg = "sb {0},{1}({2})".format(x_description[rs2], hex(imm_s), x_description[rs1])
elif f3 == 0x01:
msg = "sh {0},{1}({2})".format(x_description[rs2], hex(imm_s), x_description[rs1])
elif f3 == 0x02:
msg = "sw {0},{1}({2})".format(x_description[rs2], hex(imm_s), x_description[rs1])
elif op == 0x03:
if f3 == 0x00:
msg = "lb {0},{1}({2})".format(x_description[rd], hex(imm_i), x_description[rs1])
elif f3 == 0x01:
msg = "lh {0},{1}({2})".format(x_description[rd], hex(imm_i), x_description[rs1])
elif f3 == 0x02:
msg = "lw {0},{1}({2})".format(x_description[rd], hex(imm_i), x_description[rs1])
elif f3 == 0x04:
msg = "lbu {0},{1}({2})".format(x_description[rd], hex(imm_i), x_description[rs1])
elif f3 == 0x05:
msg = "lhu {0},{1}({2})".format(x_description[rd], hex(imm_i), x_description[rs1])
elif f3 == 0x06:
msg = "lwu {0},{1}({2})".format(x_description[rd], hex(imm_i), x_description[rs1])
elif op == 0x13:
if f3 == 0x00:
if (rd==0) and (rs1 == 0) and (imm_i == 0):
msg = "nop" # Special!
else:
msg = "addi {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x01:
msg = "slli {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x02:
msg = "slti {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x03:
msg = "sltiu {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x04:
msg = "xori {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x05:
if (f7 & 0x20) == 0x20:
msg = "srai {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
else:
msg = "srli {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x06:
msg = "ori {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif f3 == 0x07:
msg = "andi {0},{1},{2}".format(x_description[rd], x_description[rs1], hex(imm_i))
elif op == 0x0f:
if opcode == 0x100F:
msg = "fence.i (ignored)"
else:
msg = "fence {0} (ignored)".format(hex(opcode))
else:
msg = "-- illegal? --"
print("Illegal opcode detected: {0} @{1}?".format(hex(opcode),hex(pc)))
except:
msg = "-- illegal/unknown? --"
print("Unknown opcode detected: {0} @{1}?".format(hex(opcode),hex(pc)))
return msg
def printflag(val, c1, c2):
if val != 0:
print(c1, end="")
else:
print(c2, end="")
def dumpregs(wb, bWithRegs):
# DRAM loader stati
i32DRAMReadCount = wb.regs.dramtransfer_b32RCount.read()
i32DRAMReadOffset = wb.regs.dramtransfer_b9Offset.read()
i32DRAMReadData = wb.regs.dramtransfer_b32Data.read()
print("L1 cache loads: {0}\tL1[{1}] -> {2}".format(i32DRAMReadCount, i32DRAMReadOffset, hex(i32DRAMReadData)))
i32DRAMReadCount = wb.regs.dramtransfer2_b32RCount.read()
i32DRAMReadOffset = wb.regs.dramtransfer2_b9Offset.read()
i32DRAMReadData = wb.regs.dramtransfer2_b32Data.read()
print("LU cache loads: {0}\tLU[{1}] -> {2}".format(i32DRAMReadCount, i32DRAMReadOffset, hex(i32DRAMReadData)))
# Processor stati
i32mode = wb.regs.risq5_b32mode.read()
i32status = wb.regs.risq5_b32status.read()
i32FSMs = wb.regs.risq5_b32_FSMs.read()
i32pc = wb.regs.risq5_b32_PC.read()
i32opcode = wb.regs.risq5_b32_opcode.read()
i32Counters = wb.regs.risq5_b32_Counters.read()
i32Breakpoint = wb.regs.risq5_b32_breakpoint.read()
i32NextPC = wb.regs.risq5_b32_next_pc.read()
print("Mode: {0} (0000 0000 0000 ".format(hex(i32mode)), end="")
printflag(i32mode & 8, 'B', '-')
printflag(i32mode & 4, 'S', '-')
printflag(i32mode & 2, 'N', '-')
printflag(i32mode & 1, 'R', '-')
print(")")
print("Status:{0} (0000 00".format(hex(i32status)), end="")
printflag(i32status & 512, '>', '-') # Jump beyond cache
printflag(i32status & 256, '<', '-') # Jump below cache
print(" ", end="")
printflag(i32status & 128,'>', '-') # Jump beyond cache
printflag(i32status & 64, '<', '-') # Jump below cache
printflag(i32status & 32, 'V', '-') # LU cache valid
printflag(i32status & 16, '>', '-') # Branch beyond cache
print(" ", end="")
printflag(i32status & 8, '<', '-') # Branch below cache
printflag(i32status & 4, 'I', '-') # Illegal instruction
printflag(i32status & 2, 'B', '-') # Breakpoint reached
printflag(i32status & 1, 'V', '-') # L1 cache valid
print(")")
print("FSMs: {0} (L1={1} ALU={2} LU={3} DECODE={4})".format(
hex(i32FSMs),
i32FSMs & 0xF,
(i32FSMs >> 4) & 0xF,
(i32FSMs >> 8) & 0xF,
(i32FSMs >> 12) & 0x1FF
))
print("CNTs: {0} (C1={1}[Cache loads] C2={2}[Instruction count] C3={3}[Cache offset] C4={4}[reserved])".format(
hex(i32Counters),
i32Counters & 0xFF,
(i32Counters >> 8) & 0xFF,
(i32Counters >> 16) & 0x1FF, # 9-bit
(i32Counters >> 25) & 0x7F # 7-bit
))
print("BP:{0}\tNew PC:{1}".format(hex(i32Breakpoint), hex(i32NextPC)))
print("PC:{0}\tOP:{1}\t{2}".format(
hex(i32pc),
hex(i32opcode),
disassemble(i32opcode, i32pc)
))
if bWithRegs:
for i in range(32):
wb.regs.risq5_b5_wb_reg_no.write(i) # Select register
i32x[i] = wb.regs.risq5_b32_wb_reg_value_r.read() # Pick actual register value
if (i % 4) == 0:
endx = '\n'
else:
endx = ' '
print(" ", end=endx)
print("{0}/x{1}={2}".format(x_description[i], i, hex(i32x[i]), end=""))
print("\n---- [p] set pc to 0x40190000")
print("---- [b] set breakpoint (pc+=16) [e] execute 'til breakpoint [h] halt execution")
print("---- [ ] status\t[r] dump regs\t[n] to single step\t[x] to exit")