背景
问题
一个模块/对象和多个对象之间传输数据
class sender;
function notify(receiver_1 *r1, receiver_2 *r2);
r1.process_1(data);
r2.process_2(data);
endfunction
endclass
class receiver_1;
function process_1(int value);
……
endfunction
end class
class receiver_2;
function process_2(int value);
……
……
endfunction
end class
方案 - 朴素
发送方通过接收方的指针,去调用接收方的具体处理方法,并将发送数据作为参数传入
一个模块/对象和多个对象之间传输数据
直观的做法:
发送方通过接收方的指针,去调用接收方的具体处理方法,并将发送数据作为参数传入
class sender;
function notify(receiver_1 *r1, receiver_2 *r2,receiver_3 *r3 );
r1.process_1(data);
r2.process_2(data);
r3.process_3(data);
endfunction;
endclass
缺点:
增加/删除/修改观察者,都要修改sender的notify代码,两者强耦合。
思考:can we do better?
sender知道的太多。
能不能将所有的观察者归一化?然后用一个list容器容纳所有观察者,这样sender发送过程就是遍历list容器。
方案 - 订阅者模式
一个模块/对象和多个对象之间传输数据
采用观察者模式:
接收方统一继承自一个虚基类,重写基类函数,具体的观察者(接收者)的基类指针加入/退出某个发送者的群(容器observer_list),利用多态特性;
一个模块/对象和多个对象之间传输数据
采用订阅者模式:
发送方不需要知道接收方(增/删/改)的信息,只负责把数据广播出去
class sender;
function notify( );
for( int i=0, i<observer_list.size(), i++) begin
observer_list[i].process( data );
end
endfunction;
int data;
function observer_list_add(observer_base);
endclass
Analysis port support:
1-to-multiple component
All observer’s write( ) functions called when mon call aport.write(tr1):
总结
Observer pattern
模式说明:
一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知
应用场景:
当其中一个对象的变更会影响其他对象,却又不知道多少对象必须被同时变更时。
UVM应用:
UVM TLM: uvm_analysis_export
UVM Subscriber,
UVM Monitor,
UVM Coverage,
UVM Scoreboards