* TRDB -- Library and CLI Tools for RISC-V Processor Tracing
  This library provides software tooling for decompressing, compressing and
  disassembling captured execution traces of a RISC-V Core and is compliant with
  the [[https://github.com/riscv/riscv-trace-spec][RISC-V Processor Trace Specification]]. It is used together with the
  [[https://github.com/pulp-platform/trace_debugger][hardware trace module]] of the PULP project.

** Features
   =libtrdb= routines that can be used to
   + decompress trace packets
   + disassemble traces
   + Model a trace encoding source (processor interface to trace packets)

   =trdb= command line tool(s) used to
   + do the above on a CLI

  The trace source model accepts a stimuli/trace file and produces the sequence
  of packages that the [[https://github.com/pulp-platform/trace_debugger][PULP RTL]] IP would. An example of how such a trace file
  looks like can be found in =data/trdb_stimuli=. This is what the RISC-V core
  sends to the PULP hardware trace debugger each cycle. It is used by the
  testbench of the pulp hardware tracer in by employing via the DPI.

  The =trdb= binary provides functionality to decompress recorded packages and
  to compress stimuli/trace files.

** Dependencies
   Requires =libbfd.a=, =libopcodes.a=, =libiberty.a= and =libzlib.a= from
   [[https://github.com/pulp-platform/pulp-riscv-binutils-gdb][binutils]] built using the =trace_dbg_dev= branch. Build it by calling

   #+BEGIN_SRC bash
     export CFLAGS="-g -O2 -fPIC"
   ./configure --enable-targets=riscv32, x86_64-pc-linux-gnu --disable-gdb \
   --disable-ld --disable-gas --disable-gold --disable-intl --disable-gprof \
   --disable-readline --disable-sim --disable-libdecnumber
   make clean all
   #+END_SRC

** Build
   Run =make all= for a release build of =trdb= or =make debug= for a debug
   build (debug symbols, asserts, address sanitizer, debug level logging, no
   optimizations). Run =make lib= to build =libtrdb.so=, a library for using the
   C-model, the decompression and disassembly functionality. Run =make docs= to
   build the documentation with doxygen. It will be put under =doc/=.

** Usage of =trdb=
*** Compression
    =./trdb --compress TRACE-FILE= to compress the instruction sequence given in
    =TRACE-FILE= to a sequence of packets printed in a human readable format to
    stdout. Add =--binary-format pulp= to produce binary data matching the PULP
    hardware trace debugger output.

*** Decompression
    By calling =./trdb --extract --bfd ELF-BINARY PULP-BINARY-PACKETS= you can
    reconstruct the original instruction sequence, which was generated by
    running =ELF-BINARY=, from a packet sequence =PULP-BINARY-PACKETS=. The
    output will be a dump of the instruction information which could be
    recovered.

*** Disassembly
    Most of the times one is interested in the diassembled instruction sequence.
    For that there are the flags =--disassemble= (disassemble code),
    =--function-context= (clearly delimit when we are entering a function),
    =--line-numbers= (show file names and line numbers) and =--source= (mix
    disassembly with source code) which can be added to the decompression
    command. Those flags are similar to the ones in GNU objdump.

    For more information about the options, run =trdb --help=.

*** Example
    The file at =data/trdb_stimuli= was produced by running =data/interrupt= on
    [[https://github.com/pulp-platform/pulpissimo][PULPissimo]]. It contains the executed instruction sequence and some meta
    information. The executable itself is the compiled version of [[https://github.com/pulp-platform/trace_debugger/tree/master/driver/test_interrupt][this]] example.

    Let us first emulate the trace debugger hardware by calling
    #+BEGIN_SRC bash
    ./trdb --binary-format pulp --compress -o my_packets data/trdb_stimuli
    #+END_SRC
    The generated packets can be inspected with
    #+BEGIN_SRC bash
    ./trdb --binary-format pulp --dump my_packets
    #+END_SRC
    Now we can try to recover the original instruction sequence by running
    #+BEGIN_SRC bash
    ./trdb --binary-format pulp --bfd data/interrupt --extract my_packets
    #+END_SRC
    or even better to see some disassembly
    #+BEGIN_SRC bash
    ./trdb -dSsl --binary-format pulp --bfd data/interrupt --extract my_packets
    #+END_SRC


** Usage of =libtrdb=
   Always first initialize and hold a =trdb_ctx= struct by calling =trdb_new()=,
   which contains the context and state of the trace debugger functions. On
   creation it will use some sane configuration settings.

   Feel free to control the logging level by setting either the environment
   variable =TRDB_LOG= to err, info or debug before calling =trdb_new()= or
   during runtime with =trdb_set_log_priority=. Furthermore you can also hook
   your own logging function by setting it with =trdb_set_log_fn=. By default
   everything will be printf'd to stderr.

   To run the C-model call =trdb_compress_trace_step= for each cycle and keep
   passing in =struct tr_instr= describing the retired instruction of the CPU.
   The state of the execution will be recorded in =trdb_ctx=. Generated packet
   will be added to the =struct trdb_packet_head= pointer. Such a packet list
   must be freed by the user by calling =trdb_free_packet_list=.

   To reset a =trdb_ctx= to its initial state use =trdb_reset_compression= or
   =trdb_reset_decompression= depending on your usage.

   Remember to release the library context after you are finished with
   =trdb_free=.

** Tests
   There are a few tests which can be run through =make test=.

** parse-opcodes
   The code in riscv_encoding.h was generated with [[https://github.com/pulp-platform/riscv-opcodes][riscv-opcodes]], a forked
   version which also incorporates PULP specific instructions.
