2011-03-09 15:39:05| 分类: SystemVerilog | 标签: |举报 |字号大中小 订阅
对于put_port/put_export; get_port/get_export的模型前面都有介绍,对于这样的直接连接,函数调用的initiator直接指向最终target,不耗费Delta时间。而UVM_TLM_FIFO的引入,提供了内部的put/get的实现同步机制,让消费者和生产者都可以通过port直接调用。不过,带来的效果是,get/put的同步是在tlm_fifo内部的进程进行实现的,通过mailbox的同步来完成,所以会消耗Delta时间。
一个简化的uvm_tlm_fifo实现程序,便于理解tlm_fifo背后的机制。
源代码如下:
1 /**
2 ** tlm_fifo.sv
3 ** 说明: 通过简单的模型来阐述 UVM/OVM中TLM uvm_tlm_fifo
4 ** 的基本原理。直接编译运行即可。
5 ** 作者:http://electron64.blog.163.com
6 */
7 virtual class port_base#(type T=int) ; // 构造一个抽象类
8 typedef port_base#(T) this_type;
9 protected this_type port_handle; // 申明一个对象句柄(指针)
10
11 virtual task get_t(output T trans);
12 endtask // 虚函数,get_port和get_imp都必须以它为基类
13 virtual task put_t(T trans); // 虚函数,put_port和put_imp都必须以它为基类
14 endtask
15 function void connect(this_type port); // connect仅仅是实现对象句柄的赋值
16 port_handle = port;
17 endfunction // connect
18
19 endclass // port_base
20
21 class get_port#(type T=int) extends port_base#(T);
22 virtual task get_t(output T trans);
23 port_handle.get_t(trans);
24 endtask // get_t
25 endclass // get_port
26
27 class get_imp#(type T=int, type IMP=int) extends port_base#(T);
28 local IMP m_imp; // imp表示具体实现get_t()函数的对象句柄。
29 function new(IMP imp);
31 endfunction // new
32
33 virtual task get_t(output T trans);
35 endtask // get_t
36
37 endclass // get_imp
38
39 class put_port#(type T=int) extends port_base#(T);
40 virtual task put_t(T trans);
41 port_handle.put_t(trans);
42 endtask // put_t
43 endclass // put_port
44
45 class put_imp#(type T=int, type IMP=int) extends port_base#(T);
46 local IMP m_imp; // imp表示具体实现put_t()函数的对象句柄。
47 function new(IMP imp);
49 endfunction // new
50
51 virtual task put_t(T trans);
53 endtask // put_t
54
55 endclass // put_imp
56
57 class tlm_fifo#(type T=int);
58 typedef tlm_fifo#(T) this_type;
59 put_imp#(T,this_type) put_export;
60 get_imp#(T,this_type) get_export;
61
62 local mailbox #(T) m;
63
64 function new();
66 put_export = new(this);
67 get_export = new(this);
68 endfunction // new
69
70 virtual task put_t(T trans);
72 `ifdef VERBOSE
73 $display("[tlm_fifo.put_t]: Generate transaction:%d", trans);
74 `endif
75 endtask // put_t
76
77 virtual task get_t(output T trans);
79 `ifdef VERBOSE
80 $display("[tlm_fifo.get_t]: Get transaction:%d", trans);
81 `endif
82 endtask // get_t
83
84 endclass // tlm_fifo
85
86
87 class producer;
88 put_port#(int) m_put_port;
89 function new();
91 endfunction // new
92
93 task run(int num=10);
94 int trans;
95 for(int i=0; i<num; i++) begin // 顺序产生10个int类型的transaction.
96 trans = $random;
97 #
98 $display("@%0t [Producer]: Generate transaction:<%0d>", $time, trans);
99 end
100 endtask // run
101 endclass // producer
102
103 class consumer;
104 get_port#(int) m_get_port;
105 function new();
107 endfunction // new
108
109 task run(int num=10);
110 int t;
111 t = -1;
112 for(int i=0; i<num; i++) begin // 顺序产生10个int类型的transaction.
113 #i m_get_port.get_t(t);
114 $display("@%0t [Consumer]: Get transaction:@{%0d}@", $time, t);
115 end
116 endtask // run
117 endclass // consumer
118
119 module top;
120 producer p;
121 consumer c;
122 tlm_fifo f;
123 initial begin
124 p = new();
128 p.m_put_port.connect(f.put_export);
129 fork
131 p.run();
132 join
133 #10 $finish;
134 end
135 endmodule
136
评论