[[header]]
:description: RISC-V N-Trace (Nexus-based Trace)
:company: RISC-V.org
:revdate:  Feb 29, 2024
:revnumber: 1.0.0_rc14
:revremark: Stable state (during Architecture Committee review)
:url-riscv: http://riscv.org
:doctype: book
:preface-title: Preamble
:colophon:
:appendix-caption: Appendix
:title-logo-image: image:docs-resources/images/risc-v_logo.svg[pdfwidth=3.25in,align=center]
// Settings:
:experimental:
:reproducible:
:WaveDromEditorApp: wavedrom-cli
:imagesoutdir: images
:icons: font
:lang: en
:listing-caption: Listing
:sectnums:
:sectnumlevels: 5
:toclevels: 5
:toc: left
:source-highlighter: pygments
ifdef::backend-pdf[]
:source-highlighter: coderay
endif::[]
:data-uri:
:hide-uri-scheme:
:stem: latexmath
:footnote:
:xrefstyle: short
:bibtex-file: example.bib
:bibtex-order: alphabetical
:bibtex-style: apa

= RISC-V N-Trace (Nexus-based Trace) Specification
RISC-V N-Trace Task Group

// Preamble
[WARNING]
.This document is in the link:http://riscv.org/spec-state[Stable state]
====
Change is extremely unlikely.
====

[preface]
== Change Log

PDF generated on: {localdatetime}

=== Version 1.0.0_rc14
* 2024-02-29
** Fix formatting/typo spotted in PDF.
* 2024-02-28
** Renamed I-CNT/FILE Overflow to I-CNT/HIST Full.
** Other overflow/overrun/full related changes.
** Added link to reference decoder.
** More ARC review (only 8 left!).
** More ARC review notes. Especially:
** Improved introduction
** Combined last 3 chapters
* 2024-02-24
** Removed links to other specifications and cleanup 'Related Specifications' chapter.
** Fixed PDF column widths and small small fixes.
** Made all 3 PDFs same date and version (2024-02-26 and 1.0.0_rc13)
* 2024-02-23
** Made more changes (all on clarification level)
* 2024-02-22
** Made more changes (all on clarification level)
** TODO: Clarify synchronizations
* 2023-11-28
** Made obvious changes from PR#19
* The pre-public review version (older history removed)

[Preface]
== Copyright and license information

This specification is licensed under the Creative Commons Attribution 4.0 International License
(CC-BY 4.0). The full license text is available at https://creativecommons.org/licenses/by/4.0/

Copyright 2019-2024 by RISC-V International.

[Preface]
== Contributors
Key contributors to RISC-V N-Trace (Nexus-based Trace) specification in alphabetical order: +

Bruce Ableidinger (SiFive) => Initial SiFive donation, reviews +
Robert Chyla (IAR, SiFive, MIPS) => Most topics, editing, publishing +
Ernie Edgar (SiFive) => Initial SiFive donation, reviews +
Jay Gamoneda (NXP) => Reviews, updating after ARC review +
Markus Goehrle (Lauterbach) => Reviews, updates +
Nino Vidovic (Segger) => Reviews

== Introduction to N-Trace

This *RISC-V N-Trace (Nexus based trace) Specification* is based on the well-established *IEEE-5001 Nexus Standard* tailored to support the trace of RISC-V ISA cores, harts and SoC/MCU designs.

It serves multiple audiences:

* N-Trace encoder logic/IP developers.
* Validation teams testing of N-Trace implementation.
* Debug and trace tools developers.
* Software programmers utilizing the trace for debugging and performance tuning of RISC-V-based systems.

Together with the *RISC-V Trace Control Interface Specification* and *RISC-V Trace Connectors Specification* provide a complete, end-to-end, trace system for RISC-V based SoC.

Trace system is observing execution of a code and transferring trace messages (encoding the code flow and execution timing information in compressed format) for storage in the memory or transmission out of the SoC. Trace decoders will reconstruct original code flow from set of captured trace messages.

A trace ingress port (connection between the RISC-V hart and trace system) defined in the ratified *Efficient Trace for RISC-V Specification* allows the RISC-V hart to communicate execution information to the trace system. N-Trace encoder is encoding an execution flow into stream of messages. An appropriate selection of N-Trace messages (compatible with the original IEEE-5001 Nexus Standard) is described in this document.

The primary objective was to define the program flow trace messages. Extensions have been allowing for better trace compression. Future versions may include IEEE-5001 Nexus compatible data and bus trace. 

Registers controlling the N-trace decoder are defined by the *RISC-V Trace Control Interface Specification*. The control documentation is shared with E-trace so not all register and register fields are supported by N-trace.

Trace connectors defined by IEEE-5001 Nexus Standard were debug oriented, so could not be directly applied. Instead, industry standard MIPI-compliant connectors are defined in *RISC-V Trace Connectors Specification*. These connectors are pure extensions of debug-only, MIPI-compliant connectors defined by ratified *RISC-V Debug Specification*.

=== Related Specifications

This document provides reference to separated documents developed together with this *RISC-V N-Trace Specification*:

[#RISC-V_Trace_Control_Interface]
* *RISC-V Trace Control Interface Specification* - Defines RISC-V trace control interface.
** This document is intended to be shared with ratified *Efficient Trace for RISC-V Specification*.
* *RISC-V Trace Connectors Specification* - Defines RISC-V trace connectors (for external trace probes).


[#E-Trace_Specification]

Ratified *Efficient Trace for RISC-V Specification* defines RISC-V Trace Ingress Port signals (chapter *4 Instruction Trace Interface*). At the moment of this writing this is version 2.0 (ratified May 5-th 2022).

NOTE: In the future trace ingress port may be defined in separated document - in such a a case reference to E-Trace specification will not be necessary.

////
This comment is taken AS-IS from iommu_intro.adoc file
Please in ditaa figures don't use the minus key '-' in your keyboard when
typing text (like 'non-privileged' in the figure below).
'-' is a special character that is used by ditaa to draw lines, not text.
Instead use a different unicode character that looks similar.
The figure below uses the unicode character with code U+2212 instead of the '-'
character of your keyboard (which has the unicode code U+002B).
Note that in your editor both probably look the same, but when rendered by
ditaa/asciidoc the '-' from your keyboard is used to draw a line, while the
alternative looks as a minus symbol.
If you don't know how to type an unicode character in your editor you might
simply copy the '−' character in the 'non−privileged' word from the drawing
below.
Other potential unicode characters might be found in the following links:
- https://www.compart.com/en/unicode/category/Pd
- https://www.compart.com/en/unicode/bidiclass/ES
////

=== Trace Encoder Interfaces

Diagram below shows one possible implementation with only a single RISC-V hart. In a system with multiple cores/harts the *Trace Ingress Port*, *Trace Encoder Control* and *Trace Encoder* blocks should be replicated for each hart.
The main *Trace Control Layer* controlling other (shared) components in the trace system is not replicated.

[[fig:trace-encoder-interfaces]]
.Trace Encoder Interfaces
["ditaa",shadows=true, separation=false, fontsize: 14]
....

                      +--- Control register
                      |    read/write
                      |
      +----------+    V    +---------------------+     
      |          |         | Trace Control Layer |
      | Debug    |<=======>|                     |-----> Control of other
      | Module   |         |  +-------------+    |       trace components 
      |          |<------->|  |Trace Encoder|    |       (transport/storage)
      +----------+    ^    +--|  Control    |----+
            ^         |       +-------------+
            | <--- triggers,      ^
            |      stall etc.     |
            V                     | <------ Encoder control/status signals
+----------------+                |         (bits/fields in registers)
| RISC−V Hart    |                V
|          +---------+       +---------+     
|          |  Trace  |       |  Trace  |                To N−Trace transport
|          | Ingress |======>| Encoder |==============> for multiplexing/
|          |  Port   |   ^   |         |       ^        storage/export
|          +---------+   |   +---------+       |
|                |       |                     +--- Encoded trace messages
|                |       |   Ingress port           for single hart (with
+----------------+       +-- signals defined        optional source ID)
                             in E−Trace spec
....

NOTE: Placement of the Trace Encoder and Trace Control Layer are implementation dependent. 

=== Definitions and Terminology

[#Terms Used In This Specification]
.Terms Used In This Specification
[cols="25%,75%",options="header",]
|======================================================================================================
|Term| Definition
|Message|N-Trace messages are sequences of bytes. First byte of every message includes the TCODE field, which defines the type of information carried in the message and its format. When messages are transmitted or stored a protocol, described in <<N-Trace Transmission Protocol,N-Trace Transmission Protocol>> chapter, defines the start and the end of each message.

|Field| A field is a distinct piece of the information contained within a message, and messages may contain one or more fields (in addition to the first TCODE field). Fields can be either of fixed-length or variable-length. Several fields may be packet into single byte and single field may span multiple bytes. Definitions of all fields can be found in <<Fields in Messages,Fields in Messages>> chapter.

|Variable-length Field|Specifying that a field is variable-length (*Var* used as field size definition) means that the message must contain the field, but that the field's size may vary from a minimum of 1 bit. When messages are transmitted or stored, variable-length fields must end on a byte boundary. If necessary, they must zero-fill bit positions beyond the highest order bit of the variable-length data. Because variable-length fields may be of different lengths in messages of the same type, when messages are transmitted or stored a protocol, described in <<N-Trace Transmission Protocol,N-Trace Transmission Protocol>> chapter, defines the end of each variable-length field.

|Configurable Field|Configurable field (*Cfg* used as field size) means that existence and size of this field depends on some configuration setting. See <<N-Trace Specific Trace Controls,N-Trace Specific Trace Controls>> chapter for details.
|N-Trace| IEEE-5001 Nexus Standard Based Trace for RISC-V (as defined by this specification).
|E-Trace| Efficient Trace for RISC-V (as defined by <<E-Trace_Specification,E-Trace Specification>>).
|Unconditional Jump|On RISC-V ISA all jump instructions are always unconditional, but these two words are always used to avoid any confusions with the term 'branch' used by the IEEE-5001 Nexus Standard. The two main sub-categories of unconditional jumps that are relevant for tracing are: direct unconditional jump and indirect unconditional jump.
|Direct Conditional Branch|On RISC-V ISA all branch instructions are always direct and conditional (and also relative), but these three words are always used together to avoid confusions with the term 'branch' used by the IEEE-5001 Nexus Standard.
|======================================================================================================

== Trace Ingress Port

N-Trace is using the same ingress port as specified in <<E-Trace_Specification,E-Trace Specification>> (chapter *4 Instruction Trace Interface*).

* As this specification does not define the data trace yet, sub-chapters *4.3 Data Trace Interface requirements* and *4.4 Data Trace Interface* are not applicable.
* It is an ambition to extract single, shared *RISC-V Trace Ingress Port* specifications (combining this chapter with relevant E-Trace chapter). 

Table below provides a detailed mapping of of causes for terminating an instruction block to the corresponding *itype* encoding - it could be used during development of ingress port logic inside of a hart. Please be aware that not only instructions, but also arguments matter (for example jalr rd,rs1 may generate 5  different, distinct *itype* values).

[#Generating itype for different instructions]
.Generating itype for different instructions
[cols="25%,40%,35%",options="header",]
|======================================================================================================
|Instruction|Condition/Notes|itype Value
|Interrupted instruction|An interrupt trap occurred following the final retired instruction in the block|2 = Interrupt
|Exception in instruction|An exception trap that occurred following the final retired instruction in the block|1 = Exception
|Conditional branch|Non-taken                               |4 = Non-taken branch
||Taken                                   |5 = Taken branch
|ebreak, ecall, c.ebreak|ecall is reported after retirement |1 = Exception
|mret, sret|                                          |3 = Exception or interrupt return
|other instruction|not in listed in this table|0 = No special type
3+|*Values of itype (4-bit) needed for <<Implicit Return Optimization,Implicit Return Optimization>>*
|jal rd         |rd = `link`                                |9 = Inferable call
|               |rd != `link`                               |15 = Other inferable jump
|jalr rd, rs1   |rd = `link` and rs1 != `link`              |8 = Uninferable call
|               |rd = `link` and rs1 = `link` and rd != rs1 |12 = Coroutine swap
|               |rd = `link` and rs1 = `link` and rd = rs1  |8 = Uninferable call
|               |rd != `link` and rs1 = `link`              |13 = Return
|               |rd != `link` and rs1 != `link`             |14 = Other uninferable jump
|c.jal          |Implicit x1                                |9 = Inferable call
|c.jalr rs1     |rs1 = x5                                   |12 = Coroutine swap
|               |rs1 != x5                                  |8 = Uninferable call
|c.jr rs1       |rs1 = `link`                               |13 = Return
|               |rs1 != `link`                              |14 = Other uninferable jump
|c.j            |No registers, only offset                  |15 = Other inferable jump
|cm.jt          |Defined by Zcmt extension                  |15 = Other inferable jump
|cm.jalt        |Defined by Zcmt extension                  |9 = Inferable call
|cm.popret*     |Defined by Zcmp extension                  |13 = Return
3+|*Values of itype (3-bit) without <<Implicit Return Optimization,Implicit Return Optimization>>*
|jal rd         |                                           |0 = No special type
|jalr           |                                           |6 = Uninferable jump
|c.j or c.jal   |                                           |0 = No special type
|cm.jt          |Defined by Zcmt extension                  |0 = No special type
|cm.jalt        |Defined by Zcmt extension                  |0 = No special type
|cm.popret*     |Defined by Zcmp extension                  |6 = Uninferable jump
|======================================================================================================

[NOTE]
====
* Branches (*itype*=4, 5) are conditional direct branches. In RISC-V ISA all jumps, calls, returns are always unconditional.
* Symbol `link` means register *x1* or *x5* as specified in *The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA* document.
* 4-bit *itype* (codes 8..15) are only necessary when <<Implicit Return Optimization,Implicit Return Optimization>> is implemented.
* Zcmt instructions (cm.jt and cm.jalt) are considered as inferable jumps as jump tables are assumed to be static and known to the decoder.
====

Table below defines how N-Trace encoder should handle different 3-bit *itype* values on trace ingress port.

[#Handling of 3-bit itype values]
.Handling of 3-bit itype values
[cols="5%,20%,75%",options="header",]
|======================================================================================================
|#|itype|Encoder Action
|0|None below|Only update <<field_I-CNT,I-CNT>> field.
|1|Exception|Update <<field_I-CNT,I-CNT>> field. +
Emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=2 or 1. +
*IMPORTANT:* An address emitted is known at the next valid ingress port cycle.
|2|Interrupt|Update <<field_I-CNT,I-CNT>> field. +
Emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=3 or 1. +
*IMPORTANT:* An address emitted is known at the next valid ingress port cycle.
|3|Exception or interrupt return|Update <<field_I-CNT,I-CNT>> field. +
Emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=0. +
*IMPORTANT:* An address emitted is known at the next valid ingress port cycle.
|4|Non-taken branch|*For <<mode_BTM,BTM>> mode:* +
  Only update <<field_I-CNT,I-CNT>> field.

*For <<mode_HTM,HTM>> mode:* +
  Update <<field_I-CNT,I-CNT>> field. +
  Add 0 as least significant bit to HIST field. See <<HIST Field Full, HIST Field Full>> for handling of overflow.
|5|Taken branch|*For <<mode_BTM,BTM>> mode:* +
  Update <<field_I-CNT,I-CNT>> field. +
  Generate <<msg_DirectBranch,DirectBranch>> message.

*For <<mode_HTM,HTM>> mode:* +
Update <<field_I-CNT,I-CNT>> field. +
Add 1 as least significant bit to HIST field. See <<HIST Field Full, HIST Field Full>> for handling of overflow.
|6|Uninferable jump|Update <<field_I-CNT,I-CNT>> field. +
Emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=0. +
*IMPORTANT:* An address emitted is known at the next valid ingress port cycle.
|7|Reserved|-
|======================================================================================================

When ingress port is implemented as 4-bit, the general uninferable jump *itype=6* should not be generated and one of the following values should be generated instead. Encoder must handle call stack action as described in the <<Implicit Return Optimization,Implicit Return Optimization>> chapter.

[#Handling of 4-bit itype values]
.Handling of 4-bit itype values
[cols="5%,20%,63%,12%",options="header",]
|======================================================================================================
|#|itype|Encoder Action|Stack Action
|8|Uninferable call|Update <<field_I-CNT,I-CNT>> field. Emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=0|Push
|9|Inferrable call|Only update <<field_I-CNT,I-CNT>> field.|Push
|10|Reseved||-
|11|Reseved||-
|12|Co-routine swap|Update <<field_I-CNT,I-CNT>> field. +
If Pop returns the same address as PC at next valid ingress port cycle, emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=0.|Pop,Push
|13|Return|Update <<field_I-CNT,I-CNT>> field. +
If Pop returns the same address as PC at next valid ingress port cycle, emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=0.
|Pop
|14|Other uninferable jump|Update <<field_I-CNT,I-CNT>> field. +
Emit Indirect Branch message with <<field_B-TYPE,B-TYPE>>=0.|-
|15|Other inferable jump|Only update <<field_I-CNT,I-CNT>> field.|-
|======================================================================================================

IMPORTANT: N-Trace encoder does not require *cause* and *tval* ingress port signals (valid for exceptions and interrupts only) as these are not reported in N-Trace messages. N-Trace is only providing the address of an exception/interrupt handler.

NOTE: As almost every ingress port cycle is updating I-CNT it may overflow. See <<I-CNT Field Full, I-CNT Field Full>> for more details.

NOTE: If optional <<trTeInstEnAllJumps,trTeInstEnAllJumps>> bit is set, trace ingress port must report *itype*=5 (Taken branch) for all direct unconditional jumps (which are normally reported as *itype* = 0 or 15). 

== N-Trace Transmission Protocol

The IEEE-5001 Nexus Standard defines a trace messaging protocol using a number of *MDO* (Message Data Out) signals and one or two flag signals known as *MSEO* (Message Start/End Out). A Nexus message is sent or stored in a record composed of *MDO* and *MSEO*. 

N-Trace specification defines 6-bit *MDO* and 2-bit *MSEO* so both fit in a single byte.

* It allows easy storage in memory as well as sending using 1-bit/ 2-bit/ 4-bit/ 8-bit/ 16-bit parallel transport (which is supported by many existing trace probes and connectors).
* Decoding software may work on bytes and 32-bit/64-bit words and expect MSEO bits at two least significant bits of each byte.

N-Trace message transmission protocol is a strict subset of IEEE-5001 Nexus Standard trace messaging protocol.

[N-Trace subset]
.N-Trace subset
[cols="33%,20%,45%",options="header",]
|====
|Protocol Feature|Nexus Standard|N-Trace (strict subset of Nexus)
|Number of *MSEO* bits|1 or 2|2
|Number of *MDO* bits|At least 1|6
|Total (*MDO*+*MSEO*) bits|At least 2|8 (one byte)
|Order (transmitted or stored)|Vendor defined|*MSEO* before *MDO*,  least significant bit for each field first
|Max field size|Not specified|64 bits (some 32 bits or less)
|Max standard message size|Not specified|38 bytes (maximum sum of all fields)
|====

The maximum standard message size of 38 bytes in this version of the specification is
 to transmit <<msg_IndirectBranchHistSync,IndirectBranchHistSync>> message which includes TCODE/ SRC/ SYNC/ B-TYPE(5 bytes total), I-CNT(30 bits, 5 bytes), F-ADDR(63 bits, 11 bytes), HIST(32 bits, 6 bytes) TSTAMP(64 bits, 11 bytes).

While implementations may have a shorter maximum message size (e.g, due to I-CNT being smaller), they must assure that the internal FIFOs are designed to hold at least two maximum sized messages that the implementation can produce.

While decoding software may be designed to avoid dynamic memory allocation, it must nonetheless be robust enough to handle messages of any size. This is to account for scenarios where trace memory could be corrupted, such as a trace consisting entirely of zeros, which could be interpreted as an unusually long variable-length field.

Custom messages and fields may carry different payloads and may be larger than 64 bits and 38 bytes.

=== MSEO Sequences

*MSEO[1:0]* bits (located in the least significant bits of each byte) are defined by the follow rules:

* The first byte of a message sends the least significant bits of the message and is indicated by *MSEO[1:0]=00*.
* Bytes occupied by fixed-length fields are sent using *MSEO[1:0]=00*.
* The last byte of a variable-length field, that is not last byte of a message, is indicated by *MSEO[1:0]=01*.
** A variable-length field in a message always ends on a byte boundary (zero extended as needed).
** The non-last bytes of a variable-length fields are indicated by *MSEO[1:0]=00*.
* The last byte of a message is indicated by *MSEO[1:0]=11*.
** It also implies an end of the last (fixed-length or variable-lenght) field of a message.
* Idle bytes (between messages or used as padding) are indicated by *MSEO[1:0]=11* and *MDO[5:0]=111111* (entire byte is *0xFF*).
* Value of *MSEO[1:0]=10* is reserved for future extensions.

Table below provides possible sequences of *MSEO[1:0]* bits (to expand above rules - *highlighted* MSEO represent the actual function): 

[#MSEO Transitions]
.Transitions of MSEO Bits 
[cols="30%,30%",options="header",]
|====
|MSEO Function|Previous-*Current* MSEO[1:0] Sequence
|Start of message|11-*00*
|Middle of field|00 (or 01)-*00*
|End of variable-length field|00 (or 01)-*01*
|End of message|00 (or 01)-*11*
|Idle (no message)|11-*11*
|Reserved|11-*01*
|Reserved|any-*10*
|====

[NOTE]
====
Original IEEE-5001 Nexus Standard defines the MSEO protocol as follows:

* Two `1`-s followed by one `0` indicates the start of a message.
* `0` followed by two or more `1`-s indicates the end of a message.
* `0` followed by `1` followed by `0` indicates the end of a variable-length field.
* `0`-s at all other clocks during transmission of a message.
* `1`-s at all clocks during no message transmission (idle).

Dual MSEO protocol (utilized by this N-Trace specification) is a two pin mode of this general (single and dual) MSEO protocol definition.
====

=== Unified N-Trace Message Structure

Each N-Trace message has identical structure (100% compatible with IEEE-5001 Nexus Standard):

* Very first field is always fixed-length *TCODE* (Transport Code) which defines the meaning and format of subsequent fields.
* In case of simultaneous tracing from more than one hart, the second field is always fixed-length *SRC* (Message Source) field, which provides a unique ID of message source.
** This field allows trace decoders to separate messages from different trace sources (Trace Encoders, harts) without knowing any details of each of the messages.
** This method can be used to handle different (opaque) trace or debug or performance data using N-Trace transport/storage/export infrastructure. 
* One or more (fixed-length or variable-length) payload fields. Sequence and selection of these fields depend on the value of *TCODE* field.
** In some rare cases one of preceding fields may define number of following fields.
* Very last field is (optional) variable-length *TSTAMP* (Timestamp) field.   
** It may be possible to generate and analyze timestamps in a unified (simpler) way.

=== Order of bits and bytes

Order of bits and bytes:

* Trace messages/packets are considered as sequences of bytes and are always transmitted with least significant bits/bytes first.
* IEEE-5001 Nexus Standard MSEO bits are transmitted on the least significant part and bit#0 first.
* Idle state must be transmitted as all 1s MSEO and MDO bits.
* For transmission on a 16bit interface (e.g. PIB 16-bit mode), the first byte of message/packet is transmitted on the least significant part and the MSEO of the second/odd byte is transmitted on bits #8-#9 and MDO on bits #10-#15.

NOTE: Above rules allow receiving trace probes to skip idle messages.

=== PIB Idle Cycles Explained

This chapter describes N-Trace specific details about the transmission via a Pin Interface Block (PIB), as it is described in the <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.

Trace messages may start on any (positive or negative) edge of trace clock. 

IMPORTANT: Once a message is started all bits of that message must be transmitted on consecutive trace clock edges (both positive and negative).

Said so, an idle sequence may be sent using any number of trace clock edges (positive or negative).

To explain this let's assume the following serially transmitted (in 1-bit PIB mode) sequences of bits (MSEO[0] bit being first on the left):

* < `11` DDDDDD> - 8 bits in a last byte of a message (`11` = MSEO, DDDDDD = DATA bits)
* < `1*n` >      - sequence of `n`-bits long idle bits (each must be `1`)
* < `00` TTTTTT> - 8 bits in a first byte of a message (`00` = MSEO, TTTTTTT = TCODE bits)

The following 4 example sequences are all valid:

* ... < `11` DDDDDD> < `00` TTTTTT> ...           => No idle bits/cycles between consecutive messages.
* ... < `11` DDDDDD> < `1*2` > < `00` TTTTTT> ... => Two (even) idle bits.
* ... < `11` DDDDDD> < `1*3` > < `00` TTTTTT> ... => Three (odd) idle bits (second message starts at another trace clock edge).
* ... < `11` DDDDDD> < `1*8` > < `00` TTTTTT> ... => 8 idle bits (idle sequence can be considered as byte 0xFF).

NOTE: Some implementations may always send idle sequences using even (or even multiple of 8) number of trace clocks - in such a case all packets will always start on a positive or negative trace clock. But conformant trace probes must handle any number of idle clocks.

NOTE: The trace probe needs to be able to synchronize with the trace stream and to detect where the trace message boundaries are. This procedure is sometimes referred to as "message alignment synchronization" or "alignment-sync". N-Trace does not need a dedicated alignment-sync sequence, but instead idle sequences can be used for alignment-sync with PIB. This means that some trace probes can only perform alignment-sync on a PIB trace stream, if the stream does contain idle sequences at some point (i.e. if not all trace messages arrive back-to-back).

=== N-Trace Message Example

Table below shows one N-Trace message with several fields. It is an output from N-Trace dump tool (part of N-Trace reference C code) with an added *Explanation* column.

[#MDO_MSEO Examples]
.MDO and MSEO Encoding Example
[cols="7%,10%,8%,25%,50%",options="header",]
|====
|Byte|MDO [5:0]|MSEO [1:0]|Decoded (by reference tool)|Explanation
|0xFF| 111111|11 | Idle | Most likely idle, but can also be the last byte of the previous message.
|0x70| 011100|00 | TCODE[6] = 28 - IndirectBranchHist| First byte, all 6 MDO bits have TCODE.
5+|Here we could have an SRC field (it would shift the start of B-TYPE).
|0xD0| 110100|00 | BTYPE[2] = 0x0| This is a 2-bit (fixed-length) field. As B-TYPE is a fixed-length field, four most significant bits are part of the next field (I-CNT).
|0x1D| 000111|01 | ICNT[10] = 0x7D| This is a second byte of the 10-bit (value 0x7D) variable-length I-CNT field. Four least significant bits (0b1101=0xD) are define in previous MDO. Three most significant bits are all 0-s as variable-length field uses all 6 MDO bits.
|0x1D| 000111|01 | UADDR[6] = 0x7| This is a single byte variable-length U-ADDR field (with three most significant 0-s).
|0xF8| 111110|00 || Normal transfer of new field (6 least significant bits).
|0xFF| 111111|11 | HIST[12] = 0xFFE| Last byte of message. It implies the end of the 12-bit HIST field. In this field we do not have any extra most significant 0-s.
5+|Here optional TSTAMP field could be sent (previous MSEO should became 01 encoding end of HIST field, but not end of the message).
|0xFF| 111111|11 | Idle|This is idle as this is the second byte with MSEO=11 (NOTE: Last byte of message is also 0xFF).
|====

== N-Trace Specific Trace Controls

This chapter describes how fields and bits from Trace Encoder control registers (named using *trTe...* pattern) are influencing N-Trace encoder and N-Trace protocol messages. N-Trace specific clarifications, in addition to description in <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> specification are provided. 

NOTE: The table below does not provide names of Trace Encoder control registers as names of bits/fields used in Trace Control Interface are unique.

[#Details_Control_Parameters]
.Trace Encoder Parameters and Controls
[cols="30%,17%,53%",options="header",]
|======================================================================================================
|Trace Control Field|Applicability|Description
|trTeActive |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeEnable |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeInstTracing |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeEmpty |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
[[trTeInstMode]]
|trTeInstMode |*Required*|One or more of the following values: +
*3:* <<mode_BTM,BTM>> (Branch Trace Messaging) mode +
*6:* <<mode_HTM,HTM>> (History Branch Messaging) mode +
must be allowed.
[[trTeContext]]
|trTeContext|Optional|Controls generation of <<msg2_Ownership,Ownership>> messages.
|trTeInstTrigEnable |Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeInstStallOrOverflow |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeInstStallEna |Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
[[trTeInhibitSrc]]
|trTeInhibitSrc|Optional|Controls generation of <<field_SRC,SRC>> field.
[[trTeInstSyncMode]]
|trTeInstSyncMode |*Required*|Controls generation of <<Synchronizing Messages,Synchronizing Messages>> with <<field_SYNC,SYNC>> field=2.
[[trTeInstSyncMax]]
|trTeInstSyncMax |*Required*|Controls generation of <<Synchronizing Messages,Synchronizing Messages>> with <<field_SYNC,SYNC>> field=2.
|trTeFormat |*Required*|Must be set to *1* (which denotes N-Trace format).
|trTeVerMajor |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeVerMinor |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeCompType |*Required*|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
[[trTeProtocolMajor]]
|trTeProtocolMajor|*Required*|*Must be 1* to encode this version (1.0) of N-Trace protocol. *Value different than 1 is considered a non-compatible version and must be rejected by the trace tool.*
[[trTeProtocolMinor]]
|trTeProtocolMinor|*Required*|*Must be 0* to encode this version (1.0) of N-Trace protocol. *Different values are considered as down-compatible extensions as should be accepted by trace tool.* Any future non-compatible feature should be specifically enabled (by new control bits), so older tools (which never set these new bits) should work with it.
|trTeInstNoAddrDiff|Not applicable|Must be hard-coded as *0*.
|trTeInstNoTrapAddr|Not applicable|Must be hard-coded as *0*.
[[trTeInstEnSequentialJump]]
|trTeInstEnSequentialJump|Optional|See <<Sequential Jump Optimization,Sequential Jump Optimization>> chapter.
[[trTeInstEnImplicitReturn]]
|trTeInstEnImplicitReturn|Optional|See <<Implicit Return Optimization,Implicit Return Optimization>> chapter.
|trTeInstEnBranchPrediction|Not applicable|Must be hard-coded as *0*.
|trTeInstEnJumpTargetCache|Not applicable|Must be hard-coded as *0*.
[[trTeInstImplicitReturnMode]]
|trTeInstImplicitReturnMode|Optional|See <<Implicit Return Optimization,Implicit Return Optimization>> chapter.
[[trTeInstEnRepeatedHistory]]
|trTeInstEnRepeatedHistory|Optional|See <<Repeated History Optimization,Repeated History Optimization>> chapter.
[[trTeInstEnAllJumps]]
|trTeInstEnAllJumps|Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
[[trTeInstExtendAddrMSB]]
|trTeInstExtendAddrMSB|Optional|See <<Virtual Addresses Optimization, Virtual Addresses Optimization>> chapter.
[[trTeSrcID]]
|trTeSrcID|Optional|Controls generation of <<field_SRC,SRC>> field.
[[trTeSrcBits]]
|trTeSrcBits|Optional|Controls generation of <<field_SRC,SRC>> field.
|trTeInstFilters|Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|trTeDataImplemented|Not applicable|*Must be 0* as IEEE-5001 Nexus Standard data trace messages are not part of version 1.0 of N-Trace specification.
|*Other* trTeData...|Not applicable|As IEEE-5001 Nexus Standard defines data trace messages, future versions of N-Trace may allow these (as an optional extension).
|*All* trTeTrig...|Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|*All* trTeFilter...|Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
|*All* trTeComp...|Optional|See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification.
[[trTsEnable]]
|trTsEnable|Optional| Part of (potentially shared Timestamp Unit) controls generation of <<field_TSTAMP,TSTAMP>> field. See <<RISC-V_Trace_Control_Interface,RISC-V Trace Control Interface>> Specification for details of the Timestamp Unit.
|======================================================================================================

== Main N-Trace Trace Modes

IEEE-5001 Nexus Standard defines two main modes of tracing program flow:

[[mode_BTM]]
*Branch Trace Messaging using Traditional Messages* - every taken direct conditional branch is generating at least two byte message, but repeated branches may be counted and reported as a single message with a count (instead of many identical messages). In this document this mode will be called *BTM (short for Branch Trace Messaging)*

[[mode_HTM]]
*Branch Trace Messaging using Branch History Messages* - every direct conditional branch (taken or not-taken) adds a single bit to the history buffer. It is much more efficient. In this document this mode will be called **HTM (short for History Trace Messaging)**

The encoder is required to implement at least one of these modes. Both may be supported, but is not required.

IMPORTANT: The IEEE-5001 Nexus Standard defines different conformance levels. These levels are not directly applicable to N-Trace as Nexus levels always include debug levels. Different N-Trace options are provided in <<N-Trace Specific Trace Controls,N-Trace Specific Trace Controls>> chapter.

== N-Trace Messages (Overview)

IMPORTANT: Names `Indirect Branch ...` used by IEEE-5001 Nexus Standard may be confusing as RISC-V ISA only allows direct conditional (and always relative) branches. Also RISC-V ISA is differentiating jumps (unconditional flow changes) and branches (conditional flow changes), while in Nexus terminology any flow change (including exceptions/interrupts) are always named as branches. This specification is using term 'branch' and 'jump' as defined in RISC-V ISA. 

// [#Fields in Messages]
=== Fields in Messages

Table below shows all types of messages that can be generated. A single row defines all fields in particular message type (shared fields are always present in the same order).

Terms used as attributes of field:

* *[n]* fixed-length *n*-bit wide field
* *[Var]* variable-length, at least 1-bit wide, field
* *[Cfg]* configurable field (existence/size depends on the encoder configuration option)

.Fields in Messages
[cols="26%,9%,7%,7%,9%,17%,8%,10%,7%",options="header",]
|===========================================================================================
| Message ID/Field [size]|<<field_TCODE,TCODE>> [6]|<<field_SRC,SRC>> [Cfg]|<<field_SYNC,SYNC>> [4]|<<field_B-TYPE,B-TYPE>> [2]|Other fields|<<field_I-CNT,I-CNT>> [Var]|<<Address Compression,x-ADDR>> [Var]|<<field_HIST,HIST>> [Var]
|[[msg_Ownership]]<<msg2_Ownership,Ownership>>   |2    |Cfg|    |     |<<field_PROCESS,PROCESS>> *[Var]*        |    |     |
|[[msg_DirectBranch]]<<msg2_DirectBranch,DirectBranch>>          |3    |Cfg|    |     |                  |Yes |     |
|[[msg_IndirectBranch]]<<msg2_IndirectBranch,IndirectBranch>>        |4    |Cfg|    |Yes  |                  |Yes |<<field_U-ADDR,U-ADDR>>|
|[[msg_Error]]<<msg2_Error,Error>>                 |8    |Cfg|    |     |<<field_ETYPE,ETYPE>> *[4]* + <<field_ECODE,ECODE>> *[Var]*  |    |     |
|[[msg_ProgTraceSync]]<<msg2_ProgTraceSync,ProgTraceSync>>         |9    |Cfg|Yes |     |                  |Yes |<<field_F-ADDR,F-ADDR>>|
|[[msg_DirectBranchSync]]<<msg2_DirectBranchSync,DirectBranchSync>>      |11   |Cfg|Yes |     |                  |Yes |<<field_F-ADDR,F-ADDR>>|
|[[msg_IndirectBranchSync]]<<msg2_IndirectBranchSync,IndirectBranchSync>>    |12   |Cfg|Yes |Yes  |                  |Yes |<<field_F-ADDR,F-ADDR>>|
|[[msg_ResourceFull]]<<msg2_ResourceFull,ResourceFull>>          |27   |Cfg|    |     |<<field_RCODE,RCODE>> *[4]* + <<field_RDATA,RDATA>> *[Var]*|    |     |
|[[msg_IndirectBranchHist]]<<msg2_IndirectBranchHist,IndirectBranchHist>>    |28   |Cfg|    |Yes  |                  |Yes |<<field_U-ADDR,U-ADDR>>|Yes
|[[msg_IndirectBranchHistSync]]<<msg2_IndirectBranchHistSync,IndirectBranchHistSync>>|29   |Cfg|Yes |Yes  |                  |Yes |<<field_F-ADDR,F-ADDR>>|Yes
|[[msg_RepeatBranch]]<<msg2_RepeatBranch,RepeatBranch>>          |30   |Cfg|    |     |<<field_B-CNT,B-CNT>> *[Var]*           |    |     |
|[[msg_ProgTraceCorrelation]]<<msg2_ProgTraceCorrelation,ProgTraceCorrelation>>  |33   |Cfg|    |     |<<field_EVCODE,EVCODE>> *[4]* + <<field_CDF,CDF>> *[2]* |Yes |     |*Cfg*
|<<msg_other,Vendor Defined>>|56..62|Cfg 6+| Vendor defined message (dedicated *TCODE* range)
|<<msg_other,Reserved>>|other|Cfg 6+| Reserved for future extensions of N-Trace specification
|===========================================================================================

IMPORTANT: Any message may include the optional <<field_TSTAMP,TSTAMP>> *[Var,Cfg]* field as the very last field of a message (it is not shown in above table because of lack of space). It must be enabled by <<trTsEnable,trTsEnable>> control bit. Timestamp field always starts at byte-boundary (as it is always preceded by variable-length field). See <<Timestamp Reporting,Timestamp Reporting>> chapter for more details. 

[[msg_other]]
NOTE: Messages marked as *Reserved* or *Vendor Defined* should be ignored by decoders interested in program flow only.
However decoders should provide an option to display/dump them and/or generate a warning as such a message may be seen when trace capture is corrupted.
*Vendor Defined* messages can be used for prototyping, debugging, validation and maintenance purposes.

Reference code header https://github.com/riscv-non-isa/tg-nexus-trace/blob/master/refcode/c/NexRvMsg.h[NexRvMsg.h] defines all N-Trace messages in machine-readable format. Here is small snipped from this file as an example:

[source,c]
----
  // Naming:
  //    NEXM=Nexus Message, BEG/END=Beginning/End of definition,
  //    FLD/VAR=fixed/variable size field
  //    ADR=special case of variable field (without least significant bit) 
  NEXM_BEG(IndirectBranchSync, 12),
    NEXM_FLD(SYNC, 4),  
    NEXM_FLD(BTYPE, 2),
    NEXM_VAR(ICNT),
    NEXM_ADR(FADDR),
    NEXM_VAR(TSTAMP),
  NEXM_END(),

  NEXM_BEG(ResourceFull, 27),
    NEXM_FLD(RCODE, 4),
    NEXM_VAR(RDATA),
    NEXM_VAR(TSTAMP),
  NEXM_END(),

  NEXM_BEG(IndirectBranchHist, 28),
    NEXM_FLD(BTYPE, 2),
    NEXM_VAR(ICNT),
    NEXM_ADR(UADDR),
    NEXM_VAR(HIST),
    NEXM_VAR(TSTAMP),
  NEXM_END(),
----

NOTE: Reference code is using plain C-style identifiers, so the field name as *B-TYPE* will become *BTYPE*.

=== Common Fields

Table below provides details for fields which are used in more than one message type. Fields which are present in only one message are described with each message. 

.Details of Common Fields
[cols="10%,7%,18%,65%",options="header",]
|======================================================================================================
| Name | Bits | Description | Values/Notes
4+|*Fields used in many messages*
[[field_TCODE]]
| TCODE      | 6             | Transfer Code | Message header that identifies the number and/or size of fields to be transferred, and how to interpret each of the fields following it.
[[field_SRC]]
| SRC        | *Cfg* | Source of Message Transmission | Width of SRC field is defined by <<trTeSrcBits,trTeSrcBits>> control field and it may be enabled/disabled by <<trTeInhibitSrc,trTeInhibitSrc>> control bit. This optional field is used to identify the source of the message transmission. In configurations that comprise only a single hart, this field need not be transmitted. For devices that comprise multiple harts, this field must be transmitted (if enabled) as part of the message to identify the source of the message transmission. Within a given device, the SRC field bit size should be the same size across all trace encoders associated with same trace stream.
[[field_SYNC]]
| SYNC       | 4             |Reason for Synchronization| Encodings and details are provided in <<Synchronizing Messages,Synchronizing Messages>> chapter.

NOTE: The SYNC field is always sent together with the <<field_F-ADDR,F-ADDR>> field, so decoding may start from a message containing the SYNC field.
[[field_B-TYPE]]
| B-TYPE      | 2             | Branch Type | Reason for indirect flow change: +
                                *0:* Indirect control flow change (jump, call or return). +
                                *1:* Exception or interrupt (if the encoder is not capable of reporting 2 and 3). +
                                *2:* *Extension:*: Exception +
                                *3:* *Extension:*: Interrupt +
                                NOTE: Either 1-only or both 2 and 3 should be implemented and consistently reported. Extended values 2 and 3 allow trace tools to distinguish exceptions and interrupts easily.
[[field_I-CNT]]
| I-CNT       | *Var* | Instruction Count | As RISC-V allows variable-length instructions, this is a number of 16-bit (INST_LEN/2) instruction units executed/retired since the I-CNT counter was transmitted or reset.  See <<I-CNT Details,I-CNT Details>> chapter for more details.
[[field_F-ADDR]]
| F-ADDR      | *Var* | Full Target Address | Full PC address with least significant bit (which is always 0 for RISC-V) is skipped.
See <<Address Compression,Address Compression>> chapter for more details.

 NOTE: The F-ADDR field is always sent together with the <<field_SYNC,SYNC>> field.
[[field_U-ADDR]]
| U-ADDR      | *Var* | Unique part of Target Address | Unique part of PC address (XOR with recently reported address).
See <<Address Compression,Address Compression>> chapter for more details.

The U-ADDR field is always sent together with the <<field_B-TYPE,B-TYPE>> field.
[[field_HIST]]
| HIST       | *Var* | Direct Branch History map |  Most significant bit = 1 is 'stop-bit', least significant bit denotes the last direct conditional branch. See <<HIST Field Generation,HIST Field Generation>> chapter for more details. 
[[field_TSTAMP]]
| TSTAMP     | *Var* | Timestamp (optional) | It must be enabled by <<trTsEnable,trTsEnable>> control bit. See <<Timestamp Reporting,Timestamp Reporting>> chapter for more details.
|======================================================================================================

IEEE-5001 Nexus Standard does not define limits for variable-length fields, but N-Trace provides some limits. It will help to write efficient decoding software but is not limiting hardware in any way.

[#Max_Field_Sizes]
.Maximum Field Sizes
[cols="22%,30%,8%,50%",options="header",]
|======================================================================================================
|Field|Symbol|Bits|Description
[[NTRACE_MAX_SRC]]
|SRC|NTRACE_MAX_SRC|12|Determined by size of Trace Control register field. Enough for 4096 (4K) trace sources.
[[NTRACE_MAX_ICNT]]
|I-CNT|NTRACE_MAX_ICNT|22|Usually a smaller value will be sufficient. Most significant bit serves as overflow marker and I-CNT full must be generated when it is set.
[[NTRACE_MAX_ADDR]]
|F-ADDR, U-ADDR|NTRACE_MAX_ADDR|63|Least significant bit is always 0 for RISC-V addresses so 63 bits only.
[[NTRACE_MAX_HIST]]
|HIST|NTRACE_MAX_HIST|32|It includes stop-bit. This size is optimal for not wasting any bits in very often used <<msg_ResourceFull,ResourceFull>> messages.
[[NTRACE_MAX_TSTAMP]]
|TSTAMP|NTRACE_MAX_TSTAMP|64|It is certainly big enough. It corresponds to architecture defined timer and cycle count registers.
|HREPEAT|NTRACE_MAX_HREPEAT|18|Assure some trace is generated for long loops.
|======================================================================================================

== N-Trace Messages (Details)

This chapter provides a detailed description of all N-Trace messages. Overview of all fields in all messages is provided in the <<Fields in Messages,Fields in Messages>> table.

Common fields are described in the <<Common Fields,Common Fields>> chapter, but fields specific to particular message *TCODE* are explained here.

Size of field in *Bits* column may be one or more of the following values:

* *n (1..6)* - This is an *n*-bits wide, fixed-length field.
* *Var* - This is a variable-length, at least 1-bit wide field.
* *Cfg* - Size of this field depends on configuration setting (*Cfg* fields are always optional).

Each message has its own table showing all fields in that message.

IMPORTANT: Original IEEE-5001 Nexus Standard is showing tables with *TCODE* (which is sent first) in the last row. This specification shows <<Fields in Messages,Fields in Messages>> in order of sending them (the first field sent is described first). This is consistent with storage, processing and text dump order.

[[msg2_Ownership]]
=== Ownership Message

This message provides necessary context (privileged mode and Context ID assigned by operating system or hypervisor) allowing the decoder to associate program flow with different parts of code which belong to different programs. It must be explicitly enabled by the <<trTeContext,trTeContext>> control bit. It is reported in one of these three conditions:

* When an instruction which is changing privilege mode or *scontext/hcontext* CSR write instruction retired (as reported via 'priv' and 'context' field on an ingress port).
* As the next message following any trace <<Synchronizing Messages,synchronizing message>> (any message that includes the <<field_SYNC,SYNC>> field).
** If *hcontext* is implemented two messages must follow (first providing *hcontext* and second providing *scontext*). It is necessary so the decoder will be able to locate the code for a specific process. 
* At entry and returns to/from exceptions and interrupts when a privilege mode is changed.

[#Fields_Ownership]
.Ownership Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=2(0x2). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
[[field_PROCESS]]
|Var |PROCESS          |This is a variable-length field, which encodes *V* and *PRV* privilege mode bits as well as *scontext/hcontext* CSR values. Details are provided below.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

Field PROCESS is encoded as 4 sub-fields (FORMAT, PRV, V, CONTEXT). Bit layout can be defined in RTL-like syntax as follows:

 PROCESS[x+5:0] = {CONTEXT[x:0], V[0], PRV[1:0], FORMAT[1:0]}

.Encoding of PROCESS field (in LSB to MSB order)
[cols="35%,20%,12%,8%,25%",options="header",]
|======================================================================================================
|Reason|FORMAT[1:0]|PRV[1:0]|V[0]|CONTEXT[x:0]
| V and/or PRV change |00   |Yes|Yes|--
| Reserved  |01|--|--|--
| Sync or *scontext* change |10|Yes|Yes|*scontext* value
| Sync or *hcontext* change |11|Yes|Yes|*hcontext* value
|======================================================================================================

Encodings of *V/PRV* follow ISA privilege mode encodings and are encoded as follows:

 U-mode:     V=0, PRV[1:0]=00
 S-mode:     V=0, PRV[1:0]=01
 M-mode:     V=0, PRV[1:0]=11
 VU-mode:    V=1, PRV[1:0]=00
 VS-mode:    V=1, PRV[1:0]=01

All unused encodings are reserved.

Examples:

 PROCESS=0x3B2 = 0b11101_1_00_10   => scontext=0x1D,V=1,PRV[1:0]=00  (VU-mode) 
 PROCESS=0xC           0b0_11_00   => V=0,PRV[1:0]=11                (M-mode) 

[[msg2_DirectBranch]]
=== DirectBranch Message

This message is generated when the taken direct conditional branch has retired. It is applicable to <<mode_BTM,BTM>> mode only.

[#Fields_DirectBranch]
.Direct Branch Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=3(0x3). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

Last instruction in the code block (or blocks) with all inferable instructions (described by I-CNT) is a taken, direct conditional branch instruction. Next PC is determined by taking [+-]offset (from the opcode of that direct conditional branch instruction) and adding it to an address of direct conditional branch instruction.

NOTE: Non-taken direct conditional branches or direct unconditional jumps are NOT generating any trace but increase I-CNT (and direct unconditional jumps are changing PC to direct unconditional jump destination address), so PC of last instruction in code block[s] can be found.

[[msg2_IndirectBranch]]
=== IndirectBranch Message

This message is generated when an instruction causing indirect unconditional control flow change has retired or an interrupt/exception got delivered. It is applicable to <<mode_BTM,BTM>> mode only.

[#Fields_IndirectBranch]
.Indirect Branch Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=4(0x4). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|2   |B-TYPE           |Standard Branch Type (<<field_B-TYPE,B-TYPE>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var |U-ADDR           |Standard Unique Address (<<field_U-ADDR,U-ADDR>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

Last instruction in the code block (or blocks) (described I-CNT field) is an indirect unconditional control flow change (jump, call, return) instruction or this packet is generated when exception or interrupt is reported in the ingress port. Next PC is determine by applying the <<Address Compression,Address Compression>> rules using the U-ADDR field in this message.

NOTE: Not-taken direct conditional branches or direct unconditional jumps are NOT generating any trace but increase I-CNT (and direct unconditional jumps are changing PC to direct unconditional jump destination address), so PC of last instruction in code block[s] can be found.

[[msg2_Error]]
=== Error Message

Error message must be produced when internal messages FIFO overflows and trace message is lost.

[#Fields_Error]
.Error Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=8(0x8). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
[[field_ETYPE]]
|4   |ETYPE            |Standard Error Type (a subset of IEEE-5001 Nexus Standard encoding): +
*0:* FIFO overrun caused messages (one or more) to be lost. +
*1..7:* Reserved. +
*8..15:* Designated for Vendor Defined Error(s).
[[field_ECODE]]
|Var     |ECODE        |Standard Error Code (a subset of IEEE-5001 Nexus Standard encoding). A bit mask that when not equal to 0 may have one or more bits set as follows to indicate errors:  +
 *0:* Exact reason unknown/not-provided. +
 *xxxxxxx1:*   Reserved. +
 *xxxxxx1x:*   Reserved (for data trace in future). +
 *xxxxx1xx:*   Program Trace Message(s) lost. +
 *xxxx1xxx:*   Ownership Trace Message(s) lost. +
 *xxx1xxxx:*   Reserved. +
 *xx1xxxxx:*   Reserved (for data trace in future). +
 *x1xxxxxx:*   Reserved. +
 *1xxxxxxx:*    Vendor Defined Message(s) lost. +
*IMPORTANT:* Implementation may always report this field as 0. It is important to have this field always generated (as variable field) as it assures that the TSTAMP field will start at the byte boundary.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes*

Error Message must be sent immediately prior to a <<Synchronizing Messages,synchronizing message>> as soon as space is available in the Trace Encoder output queue. It is suggested to have a timestamp at the moment when the first trace messages got dropped, but it is not required.

[NOTE]
====
This message *is required* as otherwise decoder (despite the fact that restart after FIFO overflow is signaled) would not be aware that trace was lost in case of the following sequence of events:

* Trace is turned off by trigger (or from any other reason).
* Message reporting 'trace off' event is lost (due to lack of space for it).
* Trace is never restarted.
* Trace is stopped (this will not generate any trace as trace is turned off)
====

[[msg2_ProgTraceSync]]
=== ProgTraceSync Message

[#Fields_ProgTraceSync]
.Program Trace Synchronization Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=9(0x9). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|4   |SYNC             |Standard Synchronization Reason (<<field_SYNC,SYNC>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var |F-ADDR           |Standard Full Address (<<field_F-ADDR,F-ADDR>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes*

This message is generated at start/restart of trace. I-CNT field must be 0 in such a case. However, for some values of SYNC (like `External Trace Trigger`), I-CNT field may not be 0 and may be used to identify the exact PC location when that particular trigger/event happened. Field F-ADDR provides a full PC address when trigger happened.

[[msg2_DirectBranchSync]]
=== DirectBranchSync Message

[#Fields_DirectBranchSync]
.Direct Branch with Sync Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=11(0xB). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|4   |SYNC             |Standard Synchronization Reason (<<field_SYNC,SYNC>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var |F-ADDR           |Standard Full Address (<<field_F-ADDR,F-ADDR>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes*

This message is generated in the same conditions as <<msg2_DirectBranch,DirectBranch>> message, but additionally provides a reason for synchronization (SYNC field) and full PC (F-ADDR field).

[[msg2_IndirectBranchSync]]
=== IndirectBranchSync Message

[#Fields_IndirectBranchSync]
.Indirect Branch with Sync Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=12(0xC). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|4   |SYNC             |Standard Synchronization Reason (<<field_SYNC,SYNC>>) field.
|2   |B-TYPE           |Standard Branch Type (<<field_B-TYPE,B-TYPE>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var |F-ADDR           |Standard Full Address (<<field_F-ADDR,F-ADDR>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes*

This message is generated in the same conditions as <<msg2_IndirectBranch,IndirectBranch>> message, but additionally provides a reason for synchronization (SYNC field) and full PC (F-ADDR field).

[[msg2_ResourceFull]]
=== Resource Full Message

This message is emitted when the HIST mask or I-CNT counter has reached maximum value for particular encoder implementation.
It assures no information is lost as the decoder may reconstruct bigger I-CNT and HIST fields (by adding/concatenating) them.

[#Fields_ResourceFull]
.Resource Full Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=27(0x1B). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
[[field_RCODE]]
|4   |RCODE            |Standard Resource Code field (defines a meaning of RDATA fields). +
*0:* I-CNT counter has reached max value and is reported in the RDATA[0] field. See <<I-CNT Field Full,I-CNT Field Full>> chapter for more details. +
*1:* HIST field is full and is reported in the RDATA[0] field.  See <<HIST Field Full,HIST Field Full>> chapter for more details. +
*2*: *Extension:* HIST field is full and is repeated. RDATA[0] field holds HIST value and RDATA[1] field holds HREPEAT (History Repeat) value. This optional extension can be enabled via the <<trTeInstEnRepeatedHistory,trTeInstEnRepeatedHistory>> control bit. +
*3..7:* Reserved for future encodings. +
*8..15:* Designated for vendor specific encodings.
[[field_RDATA]]
|Var|RDATA [0]         |Standard For RCODE=0, this is the I-CNT field. For RCODE=1 this is the HIST field (with most significant bit=1 being stop-bit). +
*Extension:* For RCODE=2 this is the HIST field (with most significant bit=1 being stop-bit).
|Var,Cfg |RDATA [1]     |*Extension:* When RCODE=2 is reported this field includes HREPEAT (History Repeat) count.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes*

Not repeated HIST field full (RCODE=1) will usually include the longest supported by a particular encoder HIST field. However any number of HIST bits may be transmitted (from 2 to <<NTRACE_MAX_HIST,NTRACE_MAX_HIST>> bits).

Both I-CNT and HIST may became full at the same time - in such a case two Resource Full messages must be generated back to back.

[[msg2_IndirectBranchHist]]
=== IndirectBranchHist Message

[#Fields_IndirectBranchHist]
.Indirect Branch History Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=28(0x1C). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|2   |B-TYPE           |Standard Branch Type (<<field_B-TYPE,B-TYPE>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var |U-ADDR           |Standard Unique Address (<<field_U-ADDR,U-ADDR>>) field.
|Var |HIST             |Standard Branch History (<<field_HIST,HIST>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

Last instruction in the code block (or blocks) (described by HIST and I-CNT fields) is an indirect unconditional control flow change (jump, call, return) instruction or this packet is generated when exception or interrupt is reported in the ingress port. See <<HIST Field Generation,HIST Field Generation>> and <<I-CNT Details,I-CNT Details>> chapters for clarifications.

Next PC is determine by applying the <<Address Compression,Address Compression>> rules using the U-ADDR field in this message.

[[msg2_IndirectBranchHistSync]]
=== IndirectBranchHistSync Message

[#Fields_IndirectBranchHistSync]
.Indirect Branch History with Sync Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=29(0x1D). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
|4   |SYNC             |Standard Synchronization Reason (<<field_SYNC,SYNC>>) field.
|2   |B-TYPE           |Standard Branch Type (<<field_B-TYPE,B-TYPE>>) field.
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var |F-ADDR           |Standard Full Address (<<field_F-ADDR,F-ADDR>>) field.
|Var |HIST             |Standard Branch History (<<field_HIST,HIST>>) field.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

This message is generated in the same conditions as <<msg2_IndirectBranchHist,IndirectBranchHistHist>> message, but additionally provides a reason for synchronization (SYNC field) and full PC (F-ADDR field).

[[msg2_RepeatBranch]]
=== RepeatBranch Message

[#Fields_RepeatBranch]
.Repeat Branch Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=30(0x1E). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
[[field_B-CNT]]
|Var |B-CNT            |Standard Branch Count field.
Number of times the previous branch message (without a <<field_SYNC,SYNC>> field) is repeated. Generated if I-CNT, HIST and target address is the same as in the previous branch message.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

This message is reported when an identical branch message is encountered (just to save trace bandwidth). Trace decoder should just repeat handling of previous branch message B-CNT times. 

[[msg2_ProgTraceCorrelation]]
=== ProgTraceCorrelation Message

This message is emitted when the trace is disabled or stopped.

[#Fields_ProgTraceCorrelation]
.Program Trace Correlation Message Fields
[cols="10%,13%,77%",options="header",]
|======================================================================================================
|Bits|Name|Description
|6   |TCODE            |Value=33(0x21). Standard Transfer Code (<<field_TCODE,TCODE>>) field.
|Cfg |SRC              |Standard Message Source (<<field_SRC,SRC>>) field.
[[field_EVCODE]]
|4   |EVCODE           |Standard Reason to generate Program Correlation: +
                            *0:* Entry into Debug Mode. Required (do not send 4 instead!). +
                            *1:* Entry into Low-power Mode. Optional. +
                            *2..3:* Reserved for data trace. +
                            *4:* Program Trace Disabled (hart is still running). Optional. +
                            *5..7:* Reserved for future extensions of N-Trace specification. +
                            *8..15:* Designated for vendor specific encodings.
[[field_CDF]]
|2   |CDF              |Standard number of CDATA fields following it: +
                            *0:* Only I-CNT field follows and there is no HIST field. +
                            *1:* I-CNT field and single CDATA (HIST) field (for HTM trace). +  
                            *2..3:* Reserved for future extensions of N-Trace specification. +
In BTM trace mode CDF must be 0. In HTM trace mode CDF must be 1 (even if HIST field is empty, encoded as 0x1).
|Var |I-CNT            |Standard Instruction Count (<<field_I-CNT,I-CNT>>) field.
|Var,Cfg |HIST         |Standard Branch History (<<field_HIST,HIST>>) field. *This field must be present in HTM mode* so decoder does not need to read CDF to determine it's existence.
|Var,Cfg |TSTAMP       |Standard Timestamp (<<field_TSTAMP,TSTAMP>>) field.
|======================================================================================================

*Explanations and Notes* 

It provides a reason (in EVCODE field) plus I-CNT and HIST fields, which allows the decoder to determine the PC where an execution or the trace actually stopped.

== Field Encoding and Calculation Techniques

This chapter describes in detail how key fields (I-CNT, HIST, U-ADDR/F-ADDR and TSTAMP) are calculated and encoded.

=== Address Compression

Address transmissions is compliant with the IEEE-5001 Nexus Standard (most significant bit 0-s skipped) with optional extension allowing to skip identical most significant bits (following Sv39/Sv48/Sv57 address generation rules). See <<Virtual Addresses Optimization, Virtual Addresses Optimization>> chapter below for clarifications.

Rules when generating addresses:

* Only execution addresses (as seen by the hart) are reported. When virtual memory system is enabled these are virtual addresses.
* The <<field_F-ADDR,F-ADDR>> field is the full address associated with the trace event, provides a starting point for reconstructing relative addresses.
* The <<field_U-ADDR,U-ADDR>> field is a compressed address that is relative to the previous trace message with an address field. It is generated by XORing the address with the previous message.
* To decode the full address from the relative address (U-ADDR) can be XORed with the previously decoded full address.
* Address fields are sent beginning with bit 1 since all execution addresses are on a 2-byte boundaries (the least significant bit is always 0 and never sent).

Example:

[#Address XOR Compression]
.Address XOR Compression Example
[cols="10%,35%,44%,11%",options="header",]
|====
|Address    |U-ADDR XOR calculations        |F-ADDR/U-ADDR field sent            |   New REF Address
|0x3FC04    |                               |F-ADDR=1_1111_1110_0000_0010=0x1FE02|   0x3FC04
|0x3F368    | REF =0011_1111_1100_0000_0100 +
              addr=0011_1111_0011_0110_1000 +
              XOR =0000_0000_1111_0110_1100 |U-ADDR=111_1011_0110=0x7B6            |   0x3F368
|0x3E100    | REF =0011_1111_0011_0110_1000 +
              addr=0011_1110_0001_0000_0000 +
              XOR =0000_0001_0010_0110_1000 |U-ADDR=1001_0011_0100=0x934           |   0x3E100
|====

=== Virtual Addresses Optimization

This optimization must be enabled by <<trTeInstExtendAddrMSB,trTeInstExtendAddrMSB>> control bit. 

NOTE: Normally (without above bit enabled or implemented) addresses with many most significant bits=1 will be send as long packets (as variable size fields skip most significant bit=0 only). The following address *0xFFFF_FFFF_8000_31F4* (real address from Linux kernel) will be encoded as *F-ADDR=0x7FFF_FFFF_C000_18FA* (least significant 0-bit skipped). Such 63-bit variable field value will require 11 bytes to be sent (as we have 6 MDO bits in each byte).

The following additional rules are used when <<trTeInstExtendAddrMSB,trTeInstExtendAddrMSB>> control bit is implemented and set:

* If F-ADDR/U-ADDR field is sent then last (most significant) bit of the very last MDO record must be extended up to bit#63 or bit#31 (depending of XLEN of the core). It is similar to sign-extension, but it is NOT a sign bit.
* This method does NOT require trace decoder to know what is a size of virtual address or if an address is physical or virtual. Decoder must look at most significant bit of last MDO in F-ADDR/U-ADDR field and either extend or not.
* Simple implementations may not implement an enable bit and always send full address.  
** Benefits of using it on 32-bit cores is small, so it may not be implemented.  

This way of encodign allows an encoder to efficiently send:

* Any physical address.
* Any virtual address (in any mode).
* Any illegal address.

Trace encoder must implement a most significant bit detection (skipping identical 1-s or 0-s in addition to skipping identical 0-s as for any other variable size field) while sending F-ADDR/U-ADDR field. Trace decoders must do it in reverse order, which means that a sign extension (if needed) must be done after collecting the last MDO bit in an F-ADDR/U-ADDR field. Calculation of full address (as defined in <<Address Compression,Address Compression>> chapter above) must be done after sign extension of U-ADDR field.

*Example Encodings*

*Non-extended address (most significant MDO bit = 0)*

            MDO_MSEO
 #byte:  543210        <- MDO bit index (bit#5 is most significant bit)
  -------------------
    #0:  111111_00
    #1:  111111_00
    #2:  111111_00
    #3:  111111_00
    #4:  111111_00
    #5:  011111_01     <- Last MDO+MSO byte. Most significant bit #5 is 0, so NO extension.
                       F-ADDR field=0x7_FFFF_FFFF, Encoded address=0xF_FFFF_FFFE

*Extended address (most significant MDO bit = 1)*

            MDO_MSEO
 #byte:  543210        <- MDO bit index (bit#5 is most significant bit)
  -------------------
    #0:  111111_00
    #1:  111111_00
    #2:  111111_00
    #3:  111111_00
    #4:  011111_00
    #5:  111100_01     <- Last MDO+MSEO byte. Most significant bit #5 is 1, so WITH extension.
                       F-ADDR field=0xF_1FFF_FFFF, Encoded address=0xFFFF_FFFE_3FFF_FFFE

*Non-extended address (extra MDO with all 0-s prevents extension)*

            MDO_MSEO
 #byte:  543210        <- MDO bit index (bit#5 is most significant bit)
  -------------------
    #0:  111111_00
    #1:  111111_00
    #2:  111111_00
    #3:  111111_00
    #4:  111111_00
    #5:  111111_00
    #6:  000000_01     <- Last MDO+MSEO byte. Most significant bit #5 is 0, so NO extension.
                       F-ADDR field=0xF_FFFF_FFFF, Encoded address=0x1F_FFFF_FFFE

*Non-extended full 64-bit address (invalid address)*

            MDO_MSEO
 #byte:  543210        <- MDO bit index (bit#5 is most significant bit)
  -------------------
    #0:  111111_00
    #1:  111111_00
    #2:  111111_00
    #3:  111111_00
    #4:  111111_00
    #5:  111111_00
    #6:  111111_00
    #7:  111111_00
    #8:  111111_00
    #9:  111111_00
   #10:  000101_01     <- Last MDO+MSEO byte. Most significant bit #5 is 0, so NO extension.
                       F-ADDR field=0x5FFF_FFFF_FFFF_FFFF, Encoded address=0xBFFF_FFFF_FFFF_FFFE

NOTE: Address *0xBFFF_FFFF_FFFF_FFFF* is NOT a legal address in any Sv39/Sv48/Sv57 modes as it does not have all most significant bits identical. But such an address may be encountered as result of a bug and as such should be reported.

=== HIST Field Generation

When the encoder is operating in <<mode_HTM,HTM>> mode direct conditional branches do NOT generate any messages. Each conditional branch (taken or not-taken direct) adding a single bit to the internal HIST register/accumulator.If a direct conditional branch is taken, bit=1 is added at the least significant position. If a direct conditional branch is not-taken, bit=0 is added at the least significant position. HIST field accumulator may be implemented as left-shift register. 

Most significant bit value 1 in the HIST field is used as a stop-bit. It allows the HIST field to be transmitted as a variable-length field efficiently (as most significant 0-bits are not transmitted).

Examples:

 Binary(MSB-LSB):   101=0x5  (two direct conditional branches, not-taken and taken)
 Binary(MSB-LSB):  1111=0xF  (three direct conditional branches, all three taken)
 Binary(MSB-LSB): 10000=0x10 (four direct conditional branches, all four not-taken)
 Binary(MSB-LSB):     1=0x1  (no direct conditional branches at all)

The HIST field is reset (to 1, which is just a stop-bit with no bits encoding direct conditional branches) each time it is transmitted (including when any <<Synchronizing Messages,synchronizing message>> is transmitted).

As least significant bit encodes the last direct conditional branch, decoders must interpret the HIST field starting from most significant bit (the one after stop-bit = 1). This is the bit which is describing the first encountered (taken or not-taken) direct conditional branch.

==== HIST Field Full

The HIST field is usually implemented as a shift register (initialized to 1 at reset). This register is shifted left and 0 or 1 is added to it. When the most significant bit of this register becomes 1, it means that the stop-bit reached the end of the HIST register and HIST field must be sent before next bit can be added.

If this is happening, a <<msg2_ResourceFull,ResourceFull>> with the HIST field (<<field_RCODE,RCODE>>=1 or 2) must be generated.

NOTE: Trace decoders do not have to be aware about the actual size of the HIST field implemented by the encoder, however in order to allow efficient implementation of trace encoders (and also allowing HIST pattern detection) this N-Trace specification limits HIST field size to max 32-bits. Longer HIST fields would not provide much of a gain and would make repeated HIST field detection more costly (in terms of hardware resources).

When a HIST buffer is identical in two or more consecutive <<msg2_ResourceFull,ResourceFull>> messages, it can be detected and reported using the HIST + HREPEAT (History Repeat Counter) instead of many identical messages.

See <<Repeated History Optimization,Repeated History Optimization>> chapter for more details.

=== I-CNT Details

Field I-CNT (present in most messages) is counting the number of halfwords for the instruction units reported as retired.

Here are rules how encoder must calculate I-CNT field:

* Every retired instruction MUST increment I-CNT by 1 (for 16-bit instruction) or by 2 (for 32-bit instruction). Specifically:
** If an instruction is explicitly changing the PC (as jump or return), that instruction itself MUST update the I-CNT.
** An exception or interrupt before retirement of an instruction CANNOT update the I-CNT.
** An exception or interrupt after retirement of an instruction MUST update the I-CNT.
** In case of longer instructions (48-bit, 64-bit, ...) (future ISA standards or custom) I-CNT may increment by 3 or more. 
* Reset of I-CNT is described in the <<I-CNT Resets,I-CNT Resets>> chapter below.

==== I-CNT Handling in BTM mode

As an illustration, let's consider the following piece of pseudo-code (... does not matter):

[[ICNT_code]]
    0x100:  c.add ...       ; 16-bit instruction
    0x102:  b... 0x200      ; 32-bit instruction (direct conditional branch)
    0x106:  add ...         ; 32-bit instruction
    0x10A:  b... 0x300      ; 32-bit instruction (direct conditional branch)
    0x10E:  c.add ...       ; 16-bit instruction
    0x110:  add ...         ; 32-bit instruction
    0x114:  c.ebreak        ; 16-bit breakpoint (to stop the code)
    ...
    0x200:  c.add ...       ; 16-bit instruction
    0x202:  c.ebreak        ; 16-bit breakpoint (to stop the code)
    ...
    0x300:  add ...         ; 32-bit instruction
    0x304:  c.ebreak        ; 16-bit breakpoint (to stop the code)

NOTE: Syntax of address ranges: In the description below a range specified as <0x100..0x105> means that addresses 0x100 and 0x105 are both included in the address range.

Let's assume we start a trace from address 0x100 (<<msg_ProgTraceSync,ProgTraceSync>> with *I-CNT=0* and F-ADDR encoding address = 0x100 should be generated) and let's assume that we executed and collected a trace for above program (in <<mode_BTM,BTM>> mode) three times:

* First time a direct conditional branch at address 0x102 is taken.
** A <<msg_DirectBranch,DirectBranch>> message with *I-CNT=3* should be generated. It means, that a code block from <0x100..0x105> (as 6=2*3) was executed and a direct conditional branch at the end of this block was taken. Decoder will know PC=0x200 from an opcode of the direct conditional branch at an address 0x102.
** Next message should be <<msg_ProgTraceCorrelation,ProgTraceCorrelation>> with *I-CNT=1* describing range <0x200..0x201> till *c.ebreak* instruction
* Second time a direct conditional branch at address 0x102 is not-taken and a direct conditional branch at address 0x10A is taken.
** A <<msg_DirectBranch,DirectBranch>> message with *I-CNT=7* should be generated. It means, that a code block from <0x100..0x10D> (as 0xE=2*7) was executed and a direct conditional branch at the end of this block was taken. Decoder will know PC=0x300 from an opcode of the direct conditional branch at an address 0x10A.
** Next message should be <<msg_ProgTraceCorrelation,ProgTraceCorrelation>> with *I-CNT=2* describing range <0x300..0x303> till *c.ebreak* instruction.
* The third time both direct conditional branches are not-taken.
** In this case only <<msg_ProgTraceCorrelation,ProgTraceCorrelation>> with *I-CNT=10* should be generated.It is describing a range <0x100..0x113> till *c.ebreak* instructions.

NOTE: Decoder must look at each instruction in the code block to know its size. It cannot calculate *current PC+I-CNT*2* as it is UNKNOWN what is the size of the last instruction retired in that block - it may be (compressed) 16-bit or 32-bit (not-compressed) direct conditional branch. Without knowing an instruction size offset of that direct conditional branch cannot be determined.

Above we analyzed some I-CNT values. Let's consider other I-CNT values.

* *I-CNT=1* is the correct value. The only valid reason to generate a message with I-CNT=1 would be an exception (or interrupt) AFTER an instruction at address 0x100. In this case an encoder should generate an <<msg_IndirectBranch,IndirectBranch>> or <<msg_IndirectBranchSync,IndirectBranchSync>> message with I-CNT=1, B-TYPE=1 (exception) and U-ADDR/F-ADDR field encoding an address of an exception/interrupt handler.

* *I-CNT=5* is also correct (which means that exception/interrupt happened before the retirement of an instruction at an address 0x10A).

* *I-CNT=0* is also possible. It should be generated when an interrupt was pending before we started the code (and trace) and instruction at address 0x100 was not executed/retired. Another reason for I-CNT=0 may be a case, where instruction at address 0x100 will generate page fault (prefetch abort) or is illegal. 

* *I-CNT=4 or 6 or 9* are *INCORRECT values* as it would mean that only half of corresponding 32-bit instruction was executed.

IMPORTANT: Decoders must report such incorrect I-CNT values and immediately abort decoding as it means that either an encoder is not conforming to this specification or a trace was captured incorrectly. Decoding may resume at the next <<Synchronizing Messages,synchronizing message>>, but it is not mandatory for all decoders to do so.

==== I-CNT Handling in HTM mode

When the encoder is operating in <<mode_HTM,HTM>> mode, I-CNT should be incremented at every retired instruction. However direct conditional branches (from code piece above ...) will NOT generate any trace packets, but each of them will add a bit to the HIST field.

Example <<ICNT_code,code>> (used to illustrate BTM) from may generate messages with the following fields (exact types of messages depend on code not visible in that example):

* I-CNT=4, HIST=0b1_1 (most significant bit=1 is stop bit, bit pattern '1' means that first direct conditional branch was taken). Encoder should continue from address 0x200 (as the first direct conditional branch encountered was reported as taken) and I-CNT=3 describes a code in <0x100..0x105> (I-CNT=3) and <0x200..0x201> (I-CNT=1) ranges.
* I-CNT=9, HIST=0b1_01 (most significant bit=1 is stop bit, bit pattern '01' means that first direct conditional branch was not-taken and second direct conditional branch was taken). Encoder should continue from address 0x300 (as the second direct conditional branch encountered was reported as taken)  and I-CNT=2 describes a code in <0x100..0x10D> (I-CNT=7) and <0x300..0x303> (I-CNT=2) ranges.
* I-CNT=10, HIST-0b1_00 (most significant bit=1 is stop bit, bit pattern '00' means that two direct conditional branches were not-taken). Encoder should continue from address 0x10E  and I-CNT=10 describes a code in <0x100..0x113> range.

==== I-CNT Resets

I-CNT is reset in one of these two situations (as defined by IEEE-5001 Nexus Standard):

* After I-CNT field is sent in a message.
* When a trace starts or is restarted (for any reason).

==== I-CNT Field Full

When I-CNT field is full it may be reported in one of two ways:

* In BTM mode (or when the HIST buffer is empty) the <<msg_ResourceFull,ResourceFull>> message with <<field_RCODE,RCODE>>=0 should be generated.
** This message will be generated only when we have a long instruction block or when we have an infinite loop with unconditional direct jump[s].
* In HTM mode and when the HIST buffer is not empty, I-CNT counter full may be reported using a <<Synchronizing Messages,synchronizing message>> with *SYNC=4 (Sequential Instruction Counter)*.
** First choice (*ResourceFull*) is optional - second choice (*SYNC=4*) can be always generated.

To illustrate *Sequential Instruction Counter* generation let's consider the following example code:

    0x100:  c.add ...       ; 16-bit instruction
    0x102:  b... 0x200      ; 32-bit instruction (direct conditional branch)
    0x106:  c.add ...       ; 16-bit instruction
    0x108:  add ...         ; 32-bit instruction
    0x10c:  add ...         ; 32-bit instruction
    0x110:  add ...         ; 32-bit instruction
    0x114:  add ...         ; 32-bit instruction
    0x118:  add ...         ; 32-bit instruction
    0x11C:  c.ebreak        ; 16-bit breakpoint (to stop the code)

and let's assume (just for simplicity) that the I-CNT counter is 4-bit wide (most significant bit being an overflow flag) and that direct conditional branch at an address 0x102 is not-taken (so code will run from address 0x100 till breakpoint at address 0x11C).

Trace of above code should generate 3 messages:

* <<msg2_ProgTraceSync,ProgTraceSync>> (start of trace)
** SYNC=3 (Exit from Debug Mode)
** I-CNT=0 (nothing executed as we are stating)
** F-ADDR=0x80 (encoding starting address 0x100)
* <<msg2_IndirectBranchHistSync,IndirectBranchHistSync>> (I-CNT overflown to 8 after processing address 0x10C)
** SYNC=4 (Sequential Instruction Counter)
** *I-CNT=8* (see note below)
** HIST=0x2 (one not taken direct conditional branch)
** F-ADDR=0x88 (encoding address 0x110)
* <<msg2_ProgTraceCorrelation,ProgTraceCorrelation>> (from address 0x110 till end of trace at 0x11C)
** EVCODE=0 (Entry into Debug Mode)
** CDF=1 (HIST field present after I-CNT)
** *I-CNT=6* (see note below)
** HIST=0x1 (no branches)

[IMPORTANT]
==== 
* Overflown *I-CNT=8* decodes instructions from instruction at an addresses 0x100 to instruction at address 0x10C (16 bytes long address range).
* *I-CNT=6* decodes instructions from addresses 0x110 to 0x118 (12 bytes long address range). Debug Mode is entered before c.ebreak instruction (as it never retires), so c.ebreak is NOT included in I-CNT.  
====

This method should be rather easy to implement as each encoder must implement 'periodic sync' (and may implement triggers as well). These will generate synchronizing messages at any moment. The only difference between these would be different values of the SYNC field. It means a lot of already present (and required) logic can be reused.

=== Synchronizing Messages

Synchronizing messages are messages with a <<field_SYNC,SYNC>> field.
That field identifies the reason for synchronization and such messages include the <<field_F-ADDR,F-ADDR>> (full address) field to synchronize the PC with the PC observed by the encoder.

All synchronizing messages MUST fully reset the encoder state, so decoding can be started from any of synchronizing messages.

[IMPORTANT]
====
Trace requires different types of synchronization on different abstraction levels. Two major categories of synchronization are:

* *Instruction trace synchronization*: allows the trace decoder to synchronize onto an ongoing instruction trace stream. This is done via synchronizing messages, which are described in this chapter in more detail.
* *Message alignment synchronization*: allows the trace decoder to detect the trace message boundaries (i.e. start and end of a trace message) within a trace stream. This kind of synchronization is not described in this chapter. It can be done via idle cycles, and is described in the <<PIB Idle Cycles Explained,PIB Idle Cycles Explained>> chapter in more detail.
====


[#SYNC Field Values]
.SYNC Field Values
[cols="7%,18%,12%,63%",options="header",]
|====
|Value|Name |Required|Description
|0| External Trace Trigger | No | This message serves as a marker of external trigger. If trace is enabled by an external trigger SYNC=5 should be used.
|1| Exit from Reset | No | Core was reset without stopping (by watchdog for example). Address should be a reset vector, but HIST and I-CNT should provide the PC of the last instruction before reset.
|2| Periodic Synchronization | Yes | Just periodic instruction trace synchronization (to allow decoding the trace from the middle or when circular RAM buffer was wrapped around overwriting part of earlier trace). The interval for periodic instruction trace synchronization gets configured via <<trTeInstSyncMode,trTeInstSyncMode>> and <<trTeInstSyncMax,trTeInstSyncMax>>.
|3| Exit from Debug Mode | Yes | Very first synchronizing message after exit from debug mode. If trace is disabled (at exit from debug more) no messages should be generated.
|4| Sequential Instruction Counter | No | Generated when I-CNT counter is full. See <<I-CNT Field Full,I-CNT Field Full>> chapter for details.
|5| Trace Enable | No | Generated when trace is re-enabled after a gap caused by trace being disabled (e.g. due to trace filters). This must not be used for exit from debug mode (in which case SYNC=3 must be used).
|6| Trace Event | No | Serves as a marker when debug watchpoint with action=4 triggered. See *RISC-V Debug Specification* for watchpoint setting details.
|7| Restart from FIFO overrun | Yes |First synchronization after a gap caused by an internal FIFO overun. Some trace messages before this synchronization message were lost.
|8| Reserved |-| For future standard use.
|9| Exit from Power-down | No | When the hart is restarted after powered-down. Similar to SYNC=1 (Exit from Reset) described above.
|10..13| Reserved |-| For future standard use.
|14..15| Reserved |-| For vendor defined codes.
|====

Decoders should report synchronization codes reported in messages (including reserved codes) as it provides extra explanation for a program flow change. Periodic synchronization are generated to allow easier decoding (not necessarilly from the start of collected trace) and may only be reported when desired by the user (for debugging).

[IMPORTANT]
====
* All synchronizing messages fully reset the encoder state, so decoding can be started from this message.
* All synchronizing messages emit an absolute <<field_TSTAMP,TSTAMP>> field (if enabled), so decoder may report full/absolute timestamp.
====

=== Corner Cases and Sequences

Normal program flow generates a sequence of messages with I-CNT>0 (reporting at least 1 instruction retired), some HIST fields (to report direct conditional branches) and F-ADDR/U-ADDR fields (to report non-inferable unconditional flow changes).

However, sometimes normal flow is interrupted (by exception or interrupt) or some other extra event (trigger/enable/disable) happens and sequence of messages or values of some fields may be a bit unusual. Table below is trying to explain some corner cases. 

[#Corner Cases]
.Corner Cases
[cols="25%,75%",options="header",]
|====
|Sequence of events|Messages Generated
|Back to back return|Second message should have <<field_I-CNT,I-CNT>>=1 or 2 (depending on the size of the second return instruction).
|Other back to back jumps or branches|Same as above (depending on the size of a second instruction)
|Back to back exceptions|Second message with <<field_B-TYPE,B-TYPE>>=2 or 1 (Exception) and <<field_I-CNT,I-CNT>>=0 (nothing executed in between).
|Exception at interrupt destination|Same as above.
|Pending interrupt at debug mode exit|<<msg2_ProgTraceSync,ProgTraceSync>> with <<field_SYNC,SYNC>>=3 followed by message with <<field_B-TYPE,B-TYPE>>=3 or 1 (Interrupt).
|Exception at first instruction traced|<<msg2_ProgTraceSync,ProgTraceSync>> with <<field_SYNC,SYNC>>=3 followed by a message with <<field_B-TYPE,B-TYPE>>=2 or 1 (Exception).
|Trace starts disabled|<<msg2_ProgTraceCorrelation,ProgTraceCorrelation>> with <<field_EVCODE,EVCODE>>=4 (Trace Disabled). Once trace is enabled message with <<field_SYNC,SYNC>>=5 (Trace Enable).
|Hart halted with trace disabled|<<msg2_ProgTraceCorrelation,ProgTraceCorrelation>> with <<field_EVCODE,EVCODE>>=0 (Enter Debug mode) and <<field_I-CNT,I-CNT>>=0 (nothing executed). 
|====

=== Timestamp Reporting

Timestamp recording must be enabled by <<trTsEnable,trTsEnable>> trace control bit.

If timestamp is enabled all <<Synchronizing Messages,Synchronizing Messages>> include an absolute timestamp value with upper zeroes suppressed. Other message types with timestamp emit the timestamp as relative offset from last reported (absolute or relative) timestamp.

NOTE: The TSTAMP field is a variable-length field and most significant bits=0 will not be transmitted. It will provide good compression for relative and absolute timestamps.

To reconstruct the full timestamp, software begins at a <<Synchronizing Messages,synchronizing message>> and stores the TSTAMP value found there, zero-extended to the full timestamp width. Shortly after starting a trace session, even a 64-bit timestamp will typically require far less than 64 bits to transmit. Software extracts the compressed TSTAMP from each message thereafter and adds it with the previous decompressed timestamp to obtain the full timestamp value associated with this message.

The following rules must be observed:

* If timestamps are enabled, ALL <<Synchronizing Messages,Synchronizing Messages>> must include absolute TSTAMP value.
* It is not required that ALL non-synchronizing messages are always reporting timestamp.
** It may be done to save trace bandwidth or in case of sending back to back messages.
* Absolute timestamp cannot exceed 64 bits (even with 1ps resolution, 64-bit counters will overflow in about 584 years).
** Implementation may choose a smaller counter - trace tools may assume timestamp will not overflow in a single session, however it would not be very hard to add support for it.
* It is suggested that in multi-hart systems all Trace Encoders use a shared timestamp (for better trace correlation), but it is not necessary.
* Timestamp at all cases, when an address is provided should be at a time when an event leading to that particular address being sent happened.

[NOTE]
====
If the above is not possible, timestamps should be at least reported in a consistent way, so time distance between distant events (for example periodic timer interrupt every) can be reliably calculated.

It is needed to assure that time reported at exceptions/interrupt handlers will be a moment when exception or interrupt was observed.
====

== Optimization Extensions

N-Trace messages are defined as a strict subset of IEEE-5001 Nexus Standard messages. However in order to provide better compression some optional extensions are defined. Each of them shoud be by default disabled and specifically enabled to allow simpler decoder to decode non fully optimized trace. Table <<#Details_Control_Parameters,Details_Control_Parameters>> describes all control bits to enable these optimizations.

=== Sequential Jump Optimization

This optimization must be enabled by <<trTeInstEnSequentialJump,trTeInstEnSequentialJump>> control bit.

By default, the target of an indirect unconditional jump is always considered an uninferable PC discontinuity.
However, if the register that specifies the jump target was loaded with a constant then it can be
considered inferable under some circumstances. The hart must identify indirect unconditional jumps with sequentially
inferable targets and provide this information separately to the encoder. The final decision as to
whether to treat the indirect unconditional jump as inferable or not must be made by the encoder. Both the constant
load and the indirect unconditional jump must be traced as concecutive instructions in the same message in order for the decoder to be able to infer the indirect unconditional jump target.

Jump targets that are supplied via

* an *lui* or *c.lui* (a register which contains a constant), or
* an *auipc* (a register which contains a constant offset from the PC).

Such indirect unconditional jump targets are classified as sequentially inferable if the pair of instructions are retired
consecutively (i.e. the *auipc*, *lui* or *c.lui* immediately precedes the indirect unconditional jump). When decoder is processing instructions (always forward) it must encounter the *auipc*, *lui* or *c.lui* immediately directly before *jr* and then calculate target address of a jump. I-CNT in that message must span over both (consecutive) instuction.

NOTE: The restriction
that the instructions must be retired consecutively is necessary in order to minimize the additional
signals needed between the hart and the encoder, and should have a minimal impact on trace
efficiency as it is anticipated that consecutive execution will be the norm.

=== Implicit Return Optimization

This optimization must be enabled by the <<trTeInstImplicitReturnMode,trTeInstImplicitReturnMode>> control field different than 0.

Although a function return is usually an indirect unconditional jump, most programs return to the
point in the program from which the function was called using a standard calling convention. For
those programs, it is possible to determine the execution path without being explicitly notified
of the destination address of the return. The implicit return mode can result in very significant
improvements in trace encoder efficiency.

Returns can only be treated as inferable if the associated call has already been reported in an earlier
packet. The encoder must ensure that this is the case.

There are 3 possible ways of handling return address stack (values of <<trTeInstImplicitReturnMode,trTeInstImplicitReturnMode>> control field):

*Simple counting (<<trTeInstImplicitReturnMode,trTeInstImplicitReturnMode>>=1)* 

This can be accomplished by utilizing a
counter to keep track of the number of nested calls being traced. The counter increments on calls
and decrements on returns. The counter will not over or underflow, and is reset to 0 whenever a synchronization packet is sent. Returns will be
treated as inferable and will not generate a trace packet if the count is non-zero (i.e. the associated
call was already reported in an earlier packet). Such a scheme is low cost, and will work as long as programs are "well behaved". The encoder will not be able to check that the return address is actually that of the instruction following the associated call. As such, any program that modifies return addresses cannot be traced using this mode with this minimal implementation. Due to these limitations *this is NOT recommented implementation*.

*Stack with Full Addresses (<<trTeInstImplicitReturnMode,trTeInstImplicitReturnMode>>=3)* 

The encoder maintains a stack of expected return addresses (created when call is encountered), and only treat a
return as inferable if the actual return address matches the value on the stack. This is fully robust for all
programs, but is more expensive to implement. In this case, if a return address does not match the
prediction, it must be reported explicitly via a packet. This ensures that the decoder can determine which return is being reported. This method may use shadow stack if implemented by the core.

*Stack with Partial Addresses (<<trTeInstImplicitReturnMode,trTeInstImplicitReturnMode>>=2)* 

Call stack maintained by encoder may not include all addresses, but only keep some least significant part of it and use them to compare if return is matching the call or not. Changes that program making incorrect return will return to address with the same least significant portion are very slim.

IMPORTANT: Decoder does not need to know what is actual depth of the call stack implemented by encoder but for efficiency reasons it should assume max depth. N-Trace implementation should never implement call stack deeper than 32 levels. Such deep calls will be most likely 'broken' by other events/messages (like periodic SYNC).

=== Repeated History Optimization

This optimization must be enabled by the <<trTeInstEnRepeatedHistory,trTeInstEnRepeatedHistory>> control bit.

A typical loop either has a direct conditional branch at the start of a loop (which must be typically 'taken' to terminate the loop) or has a direct conditional branch at the end of the loop (which must be typically 'taken' to repeat the loop).
In the first case, the direct conditional branch is 'not-taken' most of the time and 'taken' once at the end. In the second case, the direct conditional branch is 'taken' most of the time, but 'not-taken' at the end of the loop.

Loops with many iterations such as those in functions like memcpy/strcpy have identical flow in each iteraction. Instead of sending the same history bits many times, repeated patterns can be detected and counted. This is a big saving! As an example, a memcpy of 4MB buffer using 32-bit transfers will execute at least 1M of direct conditional branches and 1M of history bits must be included in trace (it is a lot of trace).

The IEEE-5001 Nexus Standard defines a <<msg_RepeatBranch,Repeat Branch>> message. This message will provide a single <<field_B-CNT,B-CNT>> (Branch Count) field instead of generating many identical <<msg_DirectBranch,Direct Branch>> messages. But this message cannot be used in <<mode_HTM,HTM>> mode as repeated messages (Direct Branch) do not include the HIST field.

In order to allow generation of repeated history of direct conditional branches in HTM mode an extra encoding for <<field_RCODE,RCODE>>=2 in <<msg_ResourceFull,Resource Full>> message is added.

IMPORTANT: It is allowed to generate any sequence of <<msg_ResourceFull,Resource Full>> messages as long as the logically concatenated sequence of (repeated or not ...) HIST bits (excluding most significant stop-bit[s]) is the same.

Tracing of such simple, long loops would benefit from generating special messages/fields which provide counters of taken/not-taken direct conditional branches (in a way similar to <<msg_RepeatBranch,Repeat Branch>> message)

But this approach will not work with more complex code with a conditional statement (or several of them) inside of a loop.

In such a case, it is desired to detect repeated sequences of taken/not-taken direct conditional branches and instead generate many messages with HIST fields, generate a message consisting of a HIST pattern and repeat count.

Let's assume that we have a loop, which generates a long sequence of repeated taken/not-taken, taken/not-taken direct conditional branches. Trace may generate <<msg_ResourceFull,Resource Full>> messages with the following HIST records:

    Msg#1:
        TCODE=27 (ResourceFull)
        RCODE=1 (full HIST record is provided as RDATA)
        RDATA=0b1_01_0101_0101_0101_0101_0101_0101_0101 = 0x55555555
                (stop-bit + pattern 01 repeated 15 times)
    Msg#2:
        TCODE=27 (ResourceFull)
        RCODE=1 (full HIST record is provided as RDATA)
        RDATA=0b1_01_0101_0101_0101_0101_0101_0101_0101 = 0x55555555
                (stop-bit + pattern 01 repeated 15 times)
    ...
    Msg#10:
        TCODE=27 (ResourceFull)
        RCODE=1 (full HIST record is provided as RDATA)
        RDATA=0b1_01_0101_0101_0101_0101_0101_0101_0101 = 0x55555555
                (stop-bit + pattern 01 repeated 15 times)

Instead of generating many messages with identical HIST record, encoder can detect repeated pattern and generate the following single message:

    Msg#1:
        TCODE=27 (ResourceFull)
        RCODE=2 (full HIST record is provided as RDATA and 
                repeat count is provided as HREPEAT field)
        RDATA=0b1_01_0101_0101_0101_0101_0101_0101_0101 = 0x55555555
                (stop-bit + pattern 01 repeated 15 times)
        HREPEAT=10  (Repeat Count=10 instead 10 messages)

Above example shows a 2-bit pattern, but using the same technique it can be expanded to any size of pattern. Exact way to detect these patterns is not specified as it does not change encoding of messages. So, it is possible to generate the following, a bit smaller, message:

    Msg#1:
        TCODE=27 (ResourceFull)
        RCODE=2 (full HIST record is provided as RDATA and 
                repeat count is provided as HREPEAT field)
        RDATA=0b1_01 = 0x5 (stop-bit + single pattern 01)
        HREPEAT=150 (Repeat Count is bigger, but pattern is smaller)

NOTE: This type of compression (reporting shorter patterns and larger counts) may not be practical as it may save only a little. Trace is compressed a lot already and it really should not matter if we report 150 iterations of a loop in 6 or 7 bytes. Example above is provided to assure that trace encoders must handle this type of trace compression.

NOTE: When number of repeated branches is bigger than max HREPEAT counter value then several consecutive messages with max HREPEAT value should be generated. Total count represented by all these messages (sum of all HREPEAT fields) will be a number of repeated branch history message.

NOTE: HREPEAT counter should not have too many bits as it is not desired to not generate any trace messages for longer periods of time. Bigger HREPEAT will not make compression better but will produce timestamp rarelly.

== Rules of Generating Messages

This chapter directly mentions 16-bit and 32-bit instructions (from the currently ratified instruction set), but it is applicable to any size being multiple of 16-bit (as main ISA defines).

*Main Rules*

. Instructions which are not control transfer instructions and direct unconditional jumps generate no trace.
** These are called inferable instructions, where the next PC can be known from static analysis of binary code.
. Only direct conditional branches, indirect unconditional flow transfer instructions and exceptions/interrupts generate trace.
** These are called non-inferable instructions, where the next PC cannot be known from static analysis of binary code.

*Detailed Rules*

. If tracing is started (after it was disabled), a <<msg_ProgTraceSync,ProgTraceSync>> message is generated.
** This message includes the reason for a start (<<field_SYNC,SYNC>> field) and full address (<<field_F-ADDR,F-ADDR>> field).
. Any retired instruction increments <<field_I-CNT,I-CNT>> field (+1 or +2).
. The following types of instructions allow trace decoders to know the next PC (encoder should not generate any trace for them).
** Instruction which is not control transfer instructions => PC is at the next instruction (+2 or +4).
** Direct (inferable...) unconditional jump => PC is unconditional jump destination (known from PC and opcode as all unconditional jumps are PC relative).
** Not taken direct conditional branch (in BTM mode) => PC is next instruction (+2 or +4).
. Indirect, unconditional jump instruction is handled as:
** In BTM mode it generates an <<msg2_IndirectBranch,IndirectBranch>> message.
** In HTM mode it generates an <<msg2_IndirectBranchHist,IndirectBranchHist>> message. If the <<field_HIST,HIST>> field is empty <<msg2_IndirectBranch,IndirectBranch>> message may be (optionally) generated instead.
. Direct, conditional branch instruction is handled as:
** In BTM mode it generates a <<msg_DirectBranch,DirectBranch>> message (only if taken).
** In HTM mode it appends a single bit (1=taken or 0=not-taken) into the branch history buffer (<<field_HIST,HIST>> field).
. In case the trace is stopped or disabled, <<msg_ProgTraceCorrelation,ProgTraceCorrelation>> message is generated.
** It included reason (<<field_EVCODE,EVCODE>> field) and <<field_I-CNT,I-CNT>> and (optional) <<field_HIST,HIST>> field, so the last PC can be calculated. 
. In case the generated message includes <<field_I-CNT,I-CNT>>/<<field_HIST,HIST>> fields, the corresponding value is reset.
** In case I-CNT is full, <<msg_ResourceFull,ResourceFull>> message (with I-CNT counter full) is generated and I-CNT is reset.
** In case HIST is full, <<msg_ResourceFull,ResourceFull>> message (with HIST field full) is generated and HIST is reset.

*Extended Rules*

These rules are augmenting the above rules if the corresponding configuration setting is set.

. Call and return instructions maintain call stack and if return is matching a call, no trace is generated.
** This optional feature is described in detail in the <<Implicit Return Optimization,Implicit Return Optimization>> chapter.
. By default, the target of an indirect unconditional jump is always considered an uninferable PC discontinuity. However, if the register that specifies the jump target was loaded with a constant
then it can be considered inferable under some circumstances. 
** Such instruction sequences may be detected and in such a case no trace is generated.
** This optional feature is described in detail in the <<Sequential Jump Optimization,Sequential Jump Optimization>> chapter.

=== Custom Instructions

Custom instructions (or any future ratified instructions) which are not changing PC flow do not require any special treatment. Trace decoders should only look at instructions which may change PC flow and for all other instructions only advance PC (+2 or +4).

Custom instruction which may change a PC (other than simple advance to next instruction) should be traced in one of the following ways:

* If the PC just advances to the next instruction, it should only increment I-CNT. Decoder will just advance the PC.
* If the program flow changes as result of a custom instruction, the custom instruction should be traced as an indirect unconditional jump (even if it is actually not an indirect unconditional jump). That way, the destination address will be reported (as F-ADDR or U-ADDR fields). Decoder will change PC to an address specified in this message. 

Such an approach will NOT require changes/adaptation in trace decoders. To illustrate this let's consider the following piece of code with custom instruction *XYZ*:

    0x100:  add ...         ; 32-bit instruction
    0x104:  XYZ             ; 32-bit instruction (custom conditional branch to 0x200 - it does not matter if direct or indirect ...)
    0x108:  c.add ...       ; 16-bit instruction
    0x10A:  c.ebreak        ; 16-bit breakpoint (to stop the code)
    ...
    0x200:  c.add ...       ; 16-bit instruction
    0x202:  c.ebreak        ; 16-bit breakpoint (to stop the code)

It can be traced as follows (exact type of messages do not matter):

* Single message (if branch was not taken)
** *I-CNT=5*     => Instruction XYZ did not change the flow and code in range <0x100..0x10A) got executed
* Two messages (if branch was taken)
** *I-CNT=4*, *F-ADDR=0x100* (denote address 0x200)  => Code in range <0x100..0x108) got executed and next PC after instruction XYZ is 0x200
** *I-CNT=1*                                         => Code in range <0x200..0x202) got executed next

NOTE: If custom instruction will generate some other trace (for example some new type of direct conditional branch which may add HIST bit), decoders must be extended to be aware about type of this custom instruction.

NOTE: If a custom instruction cannot be mapped into one of existing *itype* encodings, it may use custome encoding. In such a case encoder (and decoder ...) must be enhanced.

=== Pseudo-code of Simple N-Trace Encoder

Code below is a simplified part of actual C-code used by the reference encoder (in C). It defines two functions:

* NTraceEncoderInit(void) - initialize state of encoder
* NTraceEncoderHandleRetired(uint64_t `addr`, uint32_t `flags`) - handle single retired instruction
** `addr` - address of retired instruction
** `info` - information about instruction (type, size, taken/non-taken)

[source,c]
----

// Use N-Trace TCODE messages
#define NEXUS_TCODE_Ownership                     2
#define NEXUS_TCODE_DirectBranch                  3
#define NEXUS_TCODE_IndirectBranch                4
#define NEXUS_TCODE_Error                         8
#define NEXUS_TCODE_ProgTraceSync                 9
#define NEXUS_TCODE_DirectBranchSync              11
#define NEXUS_TCODE_IndirectBranchSync            12
#define NEXUS_TCODE_ResourceFull                  27
#define NEXUS_TCODE_IndirectBranchHist            28
#define NEXUS_TCODE_IndirectBranchHistSync        29
#define NEXUS_TCODE_RepeatBranch                  30
#define NEXUS_TCODE_ProgTraceCorrelation          33

// Functions/macros which encode bits in 'info' (example...)
#define INFO_LINEAR   0x1   // Linear (plain instruction or not-taken BRANCH)
#define INFO_4        0x2   // If not 4, it must be 2 on RISC-V
#define INFO_INDIRECT 0x8   // Possible for most types above
#define INFO_BRANCH   0x10  // Always direct on RISC-V (may have LINEAR too)

#define InfoIsBranchTaken(info) (!((info) & INFO_LINEAR))
#define InfoIsSize32(info)      ((info) & INFO_4)
#define InfoIsBranch(info)      ((info) & INFO_BRANCH)
#define InfoIsIndirect(info)    ((info) & INFO_INDIRECT)

// Function which emit N-Trace packets (all are empty here)
void EmitFix(int nbits, uint32_t value);    // Emit fixed-size field
void EmitVar(uint64_t value);               // Emit variable size field
void EmitEnd();                             // Terminate message

// Encoder configuration options
const bool      enco_opt_branch_history = true;     // Configuration option
const uint32_t  enco_opt_limICNT    = 0x10000;      // Limit of ICNT (max is 6+6+4 bits)    
const uint32_t  enco_opt_limHIST    = 0x40000000;   // Limit of HIST (max is 5*6 bits)   

// Encoder state variables
static uint32_t encoNextEmit = 0;   // TCODE to be emitted next time
static uint32_t encoICNT = 0;       // ICNT accumulated
static uint32_t encoHIST = 1;       // HIST accumulated (most significant bit is guardian bit)
static uint64_t encoADDR = 0;       // Last emitted address

void NTraceEncoderInit()
{
    encoADDR = 0;
    encoICNT = 0;   // Empty ICNT and HIST
    encoHIST = 1;

    encoNextEmit = NEXUS_TCODE_ProgTraceSync;
}

void NTraceEncoderHandleRetired(uint64_t addr, uint32_t info)
{
    // Optionally emit what was determined previously
    if (encoNextEmit != 0)
    {
        EmitFix(6, encoNextEmit);   // Emit TCODE (as determined)

        // Emit message fields (accordingly ...)
        if (encoNextEmit == NEXUS_TCODE_ProgTraceSync)
        {
            EmitFix(4, 1);          // Emit SYNC=1  (4-bit)
            EmitVar(encoICNT);      // Emit ICNT    (variable)
            EmitVar(addr >> 1);     // Emit FADDR   (variable)
        }
        else if (encoNextEmit == NEXUS_TCODE_IndirectBranchHist || 
                 encoNextEmit == NEXUS_TCODE_IndirectBranch)
        {
            EmitFix(2, 0);                      // Emit BTYPE=0 (2-bit)
            EmitVar(encoICNT);                  // Emit ICNT    (variable)
            EmitVar((encoADDR ^ addr) >> 1);    // Emit UADDR   (variable)

            if (encoNextEmit == NEXUS_TCODE_IndirectBranchHist)
            {
                EmitVar(encoHIST);              // Emit HIST    (variable)
            }
        }
        else if (encoNextEmit == NEXUS_TCODE_DirectBranch)
        {
            EmitVar(encoICNT);                  // Emit ICNT    (variable)
        }

        EmitEnd();  // It will mark last entry with MSEO=11 and flush it

        if (encoNextEmit != NEXUS_TCODE_DirectBranch)
        {
            encoADDR = addr;  // This is new address
        }
        encoNextEmit = 0;   // Only one time

        encoICNT = 0;       // Start from 'empty' ICNT and HIST
        encoHIST = 1;
    }

    // Update ICNT
    uint32_t prevICNT = encoICNT;   // In case ICNT will overflow now, we need to emit previous value ...
    if (InfoIsSize32(info)) encoICNT += 2; else encoICNT += 1;

    // Determine type of packet (only if this is branch or indirect ...)
    if (InfoIsBranch(info))
    {
        if (enco_opt_branch_history)
        {
            // Update branch history buffer (add least significant bit)
            if (InfoIsBranchTaken(info))
                encoHIST = (encoHIST << 1) | 0; // Mark branch as taken
            else
                encoHIST = (encoHIST << 1) | 1; // Mark branch as not-taken
        }
        else
        {
            if (InfoIsBranchTaken(info))
                encoNextEmit = NEXUS_TCODE_DirectBranch;    // Emit destination address (next retired)
            else
                ;   // Not taken branch is considered as linear instruction
        }
    }
    else
    if (InfoIsIndirect(info))
    {
        if (enco_opt_branch_history)
            encoNextEmit = NEXUS_TCODE_IndirectBranchHist;  // Emit destination address (next retired)
        else
            encoNextEmit = NEXUS_TCODE_IndirectBranch;      // Emit destination address (next retired)
    }

    // Optionally emit ICNT full
    if (encoICNT > enco_opt_limICNT) // Instruction count overflown?
    {
        // Emit ResourceFull with ICNT before this instruction
        EmitFix(6, NEXUS_TCODE_ResourceFull);
        EmitFix(4, 0);                          // RCODE=0 (ICNT full)
        EmitVar(prevICNT);                      // RDATA=ICNT (before overflown)
        EmitEnd();  // It will mark last entry with MSEO=11 and flush it

        // Set ICNT for this instruction
        if (InfoIsSize32(info)) encoICNT = 2; else encoICNT = 1;
    }

    // Optionally emit HIST full
    if (encoHIST & enco_opt_limHIST) // Is HIST buffer overflown?
    {
        // Emit history BEFORE this instruction (remove least significant bit)
        EmitFix(6, NEXUS_TCODE_ResourceFull);
        EmitFix(4, 1);                          // RCODE=1 (HIST full)
        EmitVar(encoHIST >> 1);                 // RDATA=HIST (before overflown)
        EmitEnd();  // It will mark last entry with MSEO=11 and flush it

        // Keep single HIST for this branch (guardian | single least significant bit from encoHIST)
        encoHIST = (0x1 << 1) | (encoHIST & 0x1);
    }
}
----

== N-Trace Decoding Guidelines

To reconstruct the program control flow using the N-Trace encoded stream of messages (as any other compressed trace) access to opcodes of instructions which were executed is necessary. This is usually done by providing an ELF file of a program being executed, but it can also be read-out from the target. Three types of information is needed:

. Size of each instruction (16-bit or 32-bit).
. Types of all instructions (corresponding to 'itype' signal on trace ingress port - based on analysis of opcodes).
. For direct unconditional jumps and direct conditional branches an offset (to jump/branch destination) encoded in an opcode.

Decoding must start from a <<Synchronizing Messages,synchronizing message>>. The synchronizing message provides the complete PC in the <<field_F-ADDR,F-ADDR>> field. Transfers relative to this PC may then be inferred using subsequent messages till a new PC is transmitted in a subsequent synchronizing message

NOTE: In order to provide partial decoding of big trace, messages with <<field_F-ADDR,F-ADDR>> is transmitted periodically. Periodic <<field_F-ADDR,F-ADDR>> transmission is also needed to decode trace from small, wrapped around buffers.

=== Decoding Algorithm Principles

To reconstruct the control flow of the program from N-Trace messages do the following:

* Handle <<field_HIST,HIST>> field (if available and not empty)
** Analyze code from the current PC through inferable unconditional jumps (all types) and direct conditional branches (each direct conditional branch will 'consume' a single bit from the *HIST* field).
** At the end (after the least significant bit from *HIST* is processed), the PC will be of the instruction executed after the last conditional branch(either taken or not-taken).
* Handle <<field_I-CNT,I-CNT>> field (if available and not 0x0)
** Analyze code from current PC through inferable unconditional jumps (all types) - each encountered direct conditional branch must be treated as not-taken
** Each encountered instruction should subtract 1 or 2 (INST_LEN/16) from I-CNT (depending on a size of particular instruction)
** It will reach either non-inferable unconditional jump or I-CNT will become 0 to denote that some other 'event' (like exception, interrupt, trace off, trigger etc.) happened.
* At the last step the <<field_F-ADDR,F-ADDR>> or <<field_U-ADDR,U-ADDR>> field (if available) should be applied. This will be the next PC where analysis of the next trace message should start.
** This is either a destination address of indirect unconditional jump or an address of an exception/interrupt handler.
* Handle the <<field_B-CNT,B-CNT>> or <<field_RCODE,RCODE>> fields by processing data from previous trace message.


[NOTE]
=====
* Phrase *inferable unconditional jumps (all types)* include indirect unconditional jumps, which may be inferable.
* Extra fields like <<field_SYNC,SYNC>>/<<field_B-TYPE,B-TYPE>> only provide extra details, but are NOT essential for a decoder to reconstruct the PC flow.
* See https://github.com/riscv-non-isa/tg-nexus-trace/tree/master/refcode/c[N-Trace Reference Code] for simple but fully functional implementation.
=====

=== Decoding trace from multiple harts

Decoder for specific a hart should only look for messages with SRC for that particular hart. Each encoder for each enabled hart (in same trace stream) must have same 'trTeSrcBits' and different 'trTeSrcID' fields set.

=== Decoding trace of operating systems 

In case of complex operating systems (Linux etc.), where code consists of several independently built programs and libraries, decoders must be aware of different program images (e.g., ELF files) at different locations. <<msg_Ownership,Ownership>> messages should provide enough context. Decoders must be also aware of assignment of *scontext/hcontext* values for programs and processes being traced.

Operating systems may decide to migrate single process to different cores/harts. It may also be the case, when different threads from the same process (sharing code ...) will run in the same time on more than one core/hart.

=== Decoding self-modifying or JIT (Just In Time compiled) code

Trace encoder is just encoding a stream of instructions passed by ingress port from the hart running it, but decoder must be aware of types of all instructions being executed.
In case of self modifying code (or JIT code), binary image (at moment of execution) must be available to decoder. How this can be done is not in the scope of this specification.

== IEEE-5001 Nexus Standard Compliance

The IEEE-5001 Nexus Standard provides a lot of flexibility and in general N-Trace can be considered also fully compatible. There is one incompatible, small change:

* Field <<field_ECODE,ECODE>> is variable-length field (to assure TSTAMP field is on byte boundary).

Several compatible extensions are described in preceeding chapters and are marked with *Extension:* marker. Each of them is disabled by default and must be directly enabled. 

== Additional Material

*Trace Bandwidth Considerations*

SRC field (if enabled) may change the otherwise optimal layout of <<Fields in Messages,Fields in Messages>>.

*Validation Considerations*

Resource Full message with I-CNT full is rare and may not be experienced in normal code. Simplest way to generate is to have an infinite loop and (rare) interrupt handler. This loop should increment a register or memory location - this value should correspond to total accumulated I-CNT.

*Potential Future Enhancements*

Table below is proposing some future enhancements for N-Trace messages. These were discussed during the development of the N-Trace specification.

[#Future Enhancements]
.Future Enhancements
[cols="25%,17%,58%",options="header",]
|====
|Enhancement|Conformance|Notes
|Instrumentation Data Trace|Nexus Compatible|Very likely (Nexus defines appropriate messages). It will require software to be instrumented by code sending data using trace infrastructure (Arm CoreSight ITM enabled many use-cases).
|Selective Data Trace|Nexus Compatible|Very likely (Nexus defines appropriate messages). It will allow sending some data in response to triggers (from debug module or external).
|Full Data Trace|Nexus Compatible|Likely (E-Trace supports it), but necessary bandwidth may be a problem.
|Smaller field sizes|Nexus Extension|Unlikely (too much of a change). Some of the fields may be made shorter (as not all cases are needed), but it may not be justified.
|System Bus Trace|Nexus Compatible|Likely (Nexus defines appropriate messages and there is a need for more than trace of harts).
|Additional TCODE|Nexus Extension|Possible, but more real-life examples are needed to justify it.
|Single MSEO bit|Nexus Compatible|Unlikely to be considered. It may provide (12.5% instead of 25% MSEO overhead), but it is more complex to handle by both encoder and decoders.
|More MDO bits|Nexus Compatible|Very unlikely to be considered. In order to keep byte alignment, 14 or 22 or 30-bit MDO may be considered. Even 14-bit will cause a lot of 'wasted' bits.
|====

NOTE: Each of the above enhancements should be first prototyped and validated using reference C encoder/decoder.
