UVM supports ports (TLM 1) and sockets (TLM 2) as transaction-level interfaces. This post will explain TLM 1. TLM 1 seems daunting as it has many ports, exports, and “imp”s, but once you understand the basics, TLM 1 is not too difficult.
Ports
Ports define which access methods to use. There are twenty-three port classes in TLM 1. Each port is a subclass of the uvm_port_base
class, which in turn is a subclass of the uvm_tlm_if_base
class (or a subclass of the uvm_sqr_if_base
class in case of the uvm_seq_item_pull_port
). See the class diagram below.
The uvm_tlm_if_base
class and the uvm_sqr_if_base
class define the access methods of a port. By default, each method issues an error message if it is called. Each port overrides a subset of the access methods as listed below. For example, the uvm_blocking_put_port
overrides the put
method (only). This means if you call a method other than the put
, you will get an error message defined in the uvm_tlm_if_base
class.
Class \ Method | put | try_ put | can_ put | get | try_ get | can_ get | peek | try_ peek | can_ peek | transport | nb_ transport | write |
---|---|---|---|---|---|---|---|---|---|---|---|---|
uvm_blocking_ put_port | X | |||||||||||
uvm_nonblocking_ put_port | X | X | ||||||||||
uvm_put_port | X | X | X | |||||||||
uvm_blocking_ get_port | X | |||||||||||
uvm_nonblocking_ get_port | X | X | ||||||||||
uvm_get_port | X | X | X | |||||||||
uvm_blocking_ peek_port | X | |||||||||||
uvm_nonblocking_ peek_port | X | X | ||||||||||
uvm_peek_port | X | X | X | |||||||||
uvm_blocking_ get_peek_port | X | X | ||||||||||
uvm_nonblocking_ get_peek_port | X | X | X | X | ||||||||
uvm_get_peek_port | X | X | X | X | X | X | ||||||
uvm_blocking_ master_port | X | X | X | |||||||||
uvm_nonblocking_ master_port | X | X | X | X | X | X | ||||||
uvm_master_port | X | X | X | X | X | X | X | X | X | |||
uvm_blocking_ slave_port | X | X | X | |||||||||
uvm_nonblocking_ slave_port | X | X | X | X | X | X | ||||||
uvm_slave_port | X | X | X | X | X | X | X | X | X | |||
uvm_blocking_ transport_port | X | |||||||||||
uvm_nonblocking_ transport_port | X | |||||||||||
uvm_transport_port | X | X | ||||||||||
uvm_analysis_port | X |
Exports
Exports are used when you promote imps (see the next section) to a parent component. Similar to the ports, each export is a subclass of the uvm_port_base
class, which in turn is a subclass of the uvm_tlm_if_base
class (or a subclass of the uvm_sqr_if_base
class in case of the uvm_seq_item_pull_export
). See the class diagram below.
Similar to a port class, each export class supports a subset of the access methods. See the corresponding port in the table above to figure out which methods are supported.
Imps
Imps provide the implementation of access methods. To be precise, the imps delegate the implementation to the component that actually implements the access methods. The type of the component is passed as a parameter when an imp is instantiated. Similar to the ports and exports, each imp is a subclass of the uvm_port_base
class, which in turn is a subclass of uvm_tlm_if_base
class (or a subclass of the uvm_sqr_if_base
class in case of the uvm_seq_item_pull_imp
). See the class diagram below.
Similar to a port class, each imp class supports a subset of the access methods. See the corresponding port in the table above to figure out which methods are supported.
FIFOs
TLM 1 defines two FIFOs; the uvm_tlm_fifo
and the uvm_tlm_analysis_fifo
. See the component figure and the class diagram below.
Channels
TLM 1 defines two channels; the uvm_tlm_req_rsp_channel
and the uvm_tlm_transport_channel
. See the component figure and the class diagram below.
The next post will give you an example of how to use the TLM 1 classes.
What is the basic difference between import and export in TLM’s?
A component instantiates a port when the component uses a TLM interface. For example, the
uvm_driver
has theseq_item_port
, which is an object of theuvm_seq_item_pull_port
class. Since theuvm_seq_item_pull_port
class defines the TLM access methods such asget_next_item()
anditem_done()
, the driver can use these TLM methods to get a next item by callingseq_item_port.get_next_item()
, for example.A component instantiates an export when the component provides the methods of a TLM interface. For example, the
uvm_sequencer
has theseq_item_export
, which is an object of theuvm_seq_item_pull_imp
class. Theseq_item_export
calls the TLM access methods provided by theuvm_sequencer
. In other words, theuvm_sequencer
must implement theget_next_item()
anditem_done()
, etc.By connecting a port to an export, calling
seq_item_port.get_next_item()
in a driver actually executes theget_next_item()
task provided by a sequencer.Thank you for the quick reply.
So essentially the imports (in the example uvm_seq_item_pull_imp) are the one’s that actually implement the functions.
And Exports are just for connectivity purposes or in other words promoting imports to parent components.
Is my understanding correct?
Yes, that is correct. Strictly speaking, the imp itself does not implement the functions. The actual implementations are in the component that instantiates the imp. The imp just calls the functions defined in the component. Also note that there is no “import” in UVM. The imp stands for “implementation.”
Can you explain this concept with respect to a scoreboard and a monitor.
According to this, a scoreboard component (which has the seq_item_export) should “provide” the methods of a TLM interface, and a monitor should “use” a TLM interface, and thus have a uvm_seq_item_pull_port.
Visually the monitor does not seem like having a uvm_seq_item_pull_port.
Usually a scoreboard has one or more
uvm_analysis_imp
and a monitor has one or moreuvm_analysis_port
. Theuvm_seq_item_pull_port
is used in theuvm_driver
and theuvm_seq_item_pull_imp
is used in theuvm_sequencer
.Hi Keisuke,
Can I regard that export is actually the object of imp?
It depends. For example, in our tutorial, the type of
analysis_export
of thejelly_bean_sb_subscriber
isuvm_analysis_imp
, whereas the type ofjb_analysis_export
of thejelly_bean_scoreboard
isuvm_analysis_export
. However, this difference is usually transparent from the user point of view. You can connectuvm_analysis_port
to eitheruvm_analysis_export
oruvm_analysis_imp
without knowing the type.what is the differnce between implemenation port and export port.
The imp provides the implementation of the access methods such as
put
andget
. The export merely connects the imp to the parent component.Hi Shimize,
I’m not clear about the context which uvm_*_export classes are used. Could you give me a sample code?
Thank you
Cuong Tran
The
uvm_*_export
classes are used to connect theuvm_*_imp
of enclosed component to the enclosing component. In the jelly beans example, thejelly_bean_scoreboard
encloses thejelly_bean_sb_subscriber
(see Verification Components). Thejelly_bean_sb_subscriber
has auvm_analysis_imp
(calledanalysis_export
; yes, the name is confusing but this is an imp type not an export type). To promote this imp to the enclosingjelly_bean_scoreboard
, it instantiated auvm_analysis_export
.The
connect_phase
of thejelly_bean_scoreboard
connects this export to the enclosed imp.In summary, you can think the
uvm_*_export
as the connector to export the internal imp. You can see the full listing of thejelly_bean_scoreboard
in Environment.uvm_driver uses seq_item_pull_port interface uvm_seq_item_pull_port #(REQ, RSP) seq_item_port; and uses the interfaces get_next_item e.t.c provided by the uvm_sqr_if.I see the the implementation of the methods in uvm_sequencer.I see any export instantiated in uvm_sequencer but I dont see any implementation port instantiated
I am correcting the previous question.I see the implementation of imp_port in uvm_sequence
Hi Shimizu,
please can you tell what is default size tlm fifo
You can specify the size of the FIFO, when you create a
uvm_tlm_fifo
.The default size is 1. If the size is zero, there is no upper bound of the size.
When do we use the uvm_put_port? What module will need to use the uvm_put_port?
Thanks !
The
uvm_put_port
can be used if you want to callput
,try_put
, orcan_put
. Which port to use really depends on which API (functions/tasks) you want to use. For example, thejelly_bean_put_driver
in TLM 1 Example uses theuvm_put_port
in order to call theput
task.Hi Keisuke,
I am seeing a peculiar issue with the “Seq_item_port” functions. I am trying to develop a 2-stage pipelined driver where the address phase is followed by the data phase on the successive clock. On the same clock the driver must also drive the address of the next transfer. Data phase can extend for multiple clocks. The address of next transfer must be driven on the same clock when the last data byte of the current transfer is being driven
The driver can’t trigger “item.done” until it has driven all data, but it must fetch the “next” seq_item on the clock of the last data byte to know what the address of the “next” seq_item is.
I designed the data phase to first drive the last data byte on the clock, then immediately do a “get_next_item” to fetch the address and drive that on the interface on the same clock.
The problem is that during the last data byte of the last seq_item in the queue, when it tries to “get_next_item”, it sees that there are no more seq_items available, and so the loop exits and the sequence drops the objection in the same sim cycle and the sim terminates. DUT to this the last data byte is never seen on the interface.
Is there a way to make the simulator wait for some fixed time (like one clock edge) when it sees that the seq_item queue is empty, before exiting?
Or is there a way to “check” if the queue is empty before actually doing a “get”, without triggering the exit.
Thank you.
Based on your description, I assume your sequence raises/drops an objection. Probably the easiest way to control the end of
run_phase
is to let your test raise/drop an objection. Let me know if that is not the case.Hi Keisuke,
I am raising and dropping the objection in the test and not the sequence.
I see. Then you can set the drain time to wait like this:
Hi Keisuke,
What is the difference between uvm_tlm_fifo and uvm_tlm_analysis_fifo ? when to use what ?
Thanks,
Madhu
The only difference is that
uvm_tlm_analysis_fifo
has an analysis export. If you want to connect an analysis port to the FIFO, then useuvm_tlm_analysis_fifo
, otherwise useuvm_tlm_fifo
.Hey Keisuke,
Thanks for the detailed explanation. I have a doubt regarding TLM ports. Usually we connect monitor to scoreboard using TLM port to send transactions. Can we also connect driver to scoreboard using TLM ports?
Yes. If you instantiate a
uvm_analysis_port
in the driver, you can connect it to the scoreboard.