문제

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

도움이 되었습니까?

해결책

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.

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top