Skip to content

five-embeddev/riscv-gtkwave

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GTKWave(https://github.com/gtkwave/gtkwave) Alias Files and External Disassemblers for RISCV.

Programs

  • scripts/generate_csrs.py - Generate CSR Alias Files
  • src/decode_addr.cpp - Convert elf file to alias files. (Generate GTKWave Translate File)
  • src/decode_addr.cpp - Decode elf file to variable names. (GTKWave Filter process)
  • src/decode_inst.cpp - Decode opcodes to instructions. (GTKWave Filter process)

Helpers

  • src/decode_elf_addr.hpp - Decode elf files.
  • src/gtkwave_loop.hpp - Core loop for GTKWave filter process

Data

  • csr_data/ - Alias Files for CSRs
    • <csr>.gtkw - Decode fields for a given CSR

Example

Assumes gtkwave is in the path.

  • example/Makefile - Generates symbol files and runs gtkwave.

  • example/vcd-trace.gtkw - Example GTKWave save file.

  • example/main.elf - Example firmware image.

  • example/vcd-trace.vcd - Trace of main.elf running.

  • example/vcd-trace.fst - Trace of main.elf running.

  • example/symbols_data.gtkw - Symbols from example firmware image.

  • example/symbols_func.gtkw - Functions from example firmware image.

Convert files and run GTKWave.

> make run

Firmware Trace Example

Example of firmware trace

Compiling

> make
> make install PREFIX_DIR=~/.local/

Using decode_addr - interactive mode

DECODE_ELF=<elf file> ./decode_addr

Filter process for example/main.elf

e.g.

$ cd src/
$ DECODE_ELF=../example/main.elf ./decode_addr
0
-
0000
-
0000000020010000
_enter
0000000080000008
mti_count

Using decode_addr - translate mode

decode_addr <elf file> <output prefix>

  • <elf file> : RISC-V elf binary
  • <output prefix> : Prefix for output files.

e.g.

./decode_addr build_tidy/main.elf main

Creates:

  • main_data.gtkw
  • main_func.gtkw

Example Function File:

0000000020010000 _enter
...
00000000200100fe _enter
0000000020010100 main
...
0000000020010afc memset
0000000020010afe .text.end

Example Data File:

0000000080000000 ecall_count
0000000080000004 ecall_count+4
0000000080000008 timestamp
000000008000000c timestamp+4
0000000080000010 .stack.start
...
0000000080000f08 .stack.start+3832
0000000080000f0c .stack.start+3836
0000000080000f10 .heap.start
0000000080000f14 .heap.start+4
0000000080000f18 .heap.start+8
...
000000008000170c .heap.start+2044
0000000080001710 .heap.end

Using decode_inst

The decode_inst takes hex decimal opcodes as stdin and writes the decoded assembly on stdout.

e.g.

Hex opcode data from objdump.

$ tail main.disasm
20010ae2:       00000297                auipc   t0,0x0
20010ae6:       9696                    add     a3,a3,t0
20010ae8:       8286                    mv      t0,ra
20010aea:       fa8680e7                jalr    -88(a3)
20010aee:       8096                    mv      ra,t0
20010af0:       17c1                    addi    a5,a5,-16
20010af2:       8f1d                    sub     a4,a4,a5
20010af4:       963e                    add     a2,a2,a5
20010af6:       f8c374e3                bgeu    t1,a2,20010a7e <memset+0x2a>
20010afa:       b7a5                    j       20010a62 <memset+0xe>

Piped into decode_inst.

$ cat main.disasm | cut -f2 -d: | cut -c -10 | ./decode_inst  | tail
auipc   t0, 0x0
c.add   a3, t0
c.mv    t0, ra
jalr    ra, a3, -88
c.mv    ra, t0
c.addi  a5, -16
c.sub   a4, a5
c.add   a2, a5
bgeu    t1, a2, pc - 120
c.j     pc - 152