In my last post I discussed two ad hoc approaches for tracing TLM 2.0 activity in a design: using output statements to write to a text file or the terminal and using SCV transaction recording to write to a database such as SST2. If your goal is to debug the TLM-specific aspects of a design, you need to get a handle on the values of generic payload objects as they flow through the transport methods of your system. Whether or not you think printf debugging is barbaric, both ad hoc approaches force you to modify your design. More importantly for debugging, critical TLM 2.0 connectivity information is difficult to capture in trace logs.
Here’s what I mean by connectivity information. In TLM 2.0, the transport interfaces – b_transport, nb_transport_fw, and nb_transport_bw – model reads and writes between initiators and targets. An initiator is a module that initiates transactions (for example a processor); a target is a module that serves as the destination for transactions (for example a memory). An interconnect module such as an arbiter or a router is both an initiator and a target, but it doesn’t serve as the beginning or ending point of a transaction. As generic payload objects travel between initiators and targets, their "passports" might receive several stamps along the way. Figure 1 shows a design with a Processor, a Bus Bridge, and a Memory. Each arrow represents a "hop" in the lifespan of the generic payload object. A successful read or write will consist of four "hops" between the Processor and the Memory, two along the forward path and two along the backward path.
Figure 1 – a TLM 2.0 Design with an Initiator, an Interconnect, and a Target.
The –sctlmrecord feature of ncsim is based on the observation that to completely trace activity between an initiator and a target, each read or write should be broken up into a sequence of snapshots as generic payload objects progress through a series of hops. -sctlmrecord traces all the fields of the generic payload object and the before and after values of transport function parameters at each hop by recording an SST2 transaction into the database. Each read or write is modeled as a sequence of transactions. Connectivity information is captured by linking those transactions through SST2 parent/child relationships. The rules of TLM 2.0 determine when to terminate a transaction sequence (i.e. when the read or write has finished). Transactions that pass through calls to b_transport have completed when the call (which blocks) returns. Thus the timing points of a b_transport call can be determined by calling sc_time_stamp immediately before and after the call to b_transport. Determining when a transaction that passes through calls to nb_transport_fw and nb_transport_bw is complete is handled by the generic payload’s memory manager. The use of the non-blocking interfaces requires that a memory manager be set for each generic payload object. When the last component relinquishes control of the object and is available for pooling or deletion, the last "hop" of the transport chain has been finished.
The following ncsim command line options control TLM 2.0 tracing:
Turns on TLM 2.0 tracing mode for designs using transport calls:
Specifies the database for TLM 2.0 tracing data:
Excludes recording of data transferred across the transport boundary, which improves efficiency because transferred data could be very large. Without this flag the data field is recorded as a string in hexadecimal format.
When you launch ncsim with –sctlmrecord, a transaction stream is created for each Initiator that actively participates in the design. Figure 2 shows two TLM 2.0 tracing streams in the Simvision Design Browser that are associated with initiator sockets in a DMA block (sc_main.TOP_TB.TOP.dma_0):
Figure 2 – A design with two initiator sockets.
Either during or after simulation, you can send TLM 2.0 tracing streams to the Simvision Waveform viewer to get a quick view of TLM 2.0 activity (Figure 3). For this design there is some activity between 4000 and 9000 ns, but things don’t really get “warmed up” until 10000 ns.
Figure 3 – High Level view of TLM 2.0 tracing activity.
Here’s a typical debugging scenario. You notice a latency in your design and have narrowed it down to activity between 5400 and 6000 ns. To use sctlmrecord to help shine light on the problem, first launch ncsim with –sctlmrecord. At the tcl prompt, immediately turn recording off. That’s right. You don’t want to record transactions until you get to the interesting part of your simulation, which is 5400 ns. Note that any read or write in progress at time 5400 will not be recorded. Only reads and writes that begin after the start time make it into the database. Future versions of Incisive SystemC will support a full command interface for toggling tracing, but in IUS 8.2 you turn tracing off by issuing the following c function call:
ncsim> call sc_tlm_record_off
Next, run to ahead:
Now you’re ready to go. Turn tracing back on and run until time 6000 ns:
ncsim> call sc_tlm_record_on
When control returns, you’ll be ready to analyze the interesting part of your design – the bottleneck. In my next post, I’ll cover exactly how to do this using Simvision, the database produced by sctlmrecord, and TxE.