Domanda

I have an analysis port connected to 3 scoreboards. When a write is done on the analysis port, the subscribers (scoreboards) are called in a certain order. But I want them to be called in a different order.

The practical use case for explicit ordering is the following. One scoreboard only does logging, so it should be called first. The other scoreboard does very basic lower level checks, so it should be called second. The third scoreboard does very complex higher level checks, so it should be called last.

SV snippet:

sb1 = scoreboard_1::type_id::create("sb1", null);
sb2 = scoreboard_2::type_id::create("sb2", null);
sb3 = scoreboard_3::type_id::create("sb3", null);

// Connect analysis port to scoreboard
m_ap = new("ap", null);
m_ap.connect(sb2.m_imp);
m_ap.connect(sb3.m_imp);
m_ap.connect(sb1.m_imp);
m_ap.resolve_bindings();

// Write
m_ap.write(10);

Current output:

# UVM_INFO design.sv(15) @ 0: sb1 [write] scoreboard_1
# UVM_INFO design.sv(32) @ 0: sb2 [write] scoreboard_2
# UVM_INFO design.sv(49) @ 0: sb3 [write] scoreboard_3

How do I control the order that the subscribers are called in? I want them to be in this order:

  • scoreboard_3
  • scoreboard_2
  • scoreboard_1

Example code on EDA Playground: http://www.edaplayground.com/x/2zQ

È stato utile?

Soluzione

The providers for the analysis port end up inside an associative array of strings when you call connect(). When doing a foreach on it (see resolve_bindings()), you will get the items in lexicographical order. This only works due to the current implementation of UVM; a future implementation may decide to use associative arrays of objects, for which there is no ordering defined.

The main idea behind analysis ports is that they needn't be connected. This means that each subscriber is supposed to be totally independent of any other subscribers connected to that port so you can't rely on any ordering.

If you want to make sure that your writes get executed in a specific order you should enforce it via your testbench structure: either have a top level scoreboard that is connected to your AP which delegates the calls in the specific order or chain together your scoreboards so that scoreboard1 does it's thing and then writes to scoreboard2, which does it's thing then writes to scoreboard3.

Altri suggerimenti

In the major simulators (ModelSim/Questa, INCISIV, and VCS) the order of the string associative arrays in uvm_port_base.svh is alphabetical. That means the order of analysis port writes corresponds to the alphabetical order of subscriber names.

To get the subscriber writes in the requested order, modify the names to something like:

sb1 = scoreboard_1::type_id::create("-sb1", null);
sb2 = scoreboard_2::type_id::create("--sb2", null);
sb3 = scoreboard_3::type_id::create("---sb3", null);

And you'll see the output change to:

# UVM_INFO design.sv(49) @ 0: ---sb3 [write] scoreboard_3
# UVM_INFO design.sv(32) @ 0: --sb2 [write] scoreboard_2
# UVM_INFO design.sv(15) @ 0: -sb1 [write] scoreboard_1

Fix on EDA Playground: http://www.edaplayground.com/x/3bf

The order in which the subscribers are called is "undefined"; that is if you move between simulators the order may change. Hence you have to design your code to work without relying on the order.

If order is important, make it explicit in the code (i.e. composite your behaviour into one larger scoreboard which then delegates in order). Don't rely on undocumented behaviour.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top