
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);
30 m_imp = imp;
31 endfunction // new
32
33 virtual task get_t(output T trans);
34 m_imp.get_t(trans); // 调用实现对象对应的get_t()函数
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);
48 m_imp = imp;
49 endfunction // new
50
51 virtual task put_t(T trans);
52 m_imp.put_t(trans); // 调用实现对象对应的put_t()函数
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();
65 m = new(1);
66 put_export = new(this);
67 get_export = new(this);
68 endfunction // new
69
70 virtual task put_t(T trans);
71 m.put(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);
78 m.get(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();
90 m_put_port = new();
91 endfunction // new
92
93 task run(int num=10);
94 int trans;
95 for(int i=0; i
96 trans = $random;
97 #5 m_put_port.put_t(trans);
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();
106 m_get_port = new();
107 endfunction // new
108
109 task run(int num=10);
110 int t;
111 t = -1;
112 for(int i=0; i
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();
125 c = new();
126 f = new();
127 c.m_get_port.connect(f.get_export); //通过句柄赋值进行连接
128 p.m_put_port.connect(f.put_export);
129 fork
130 c.run();
131 p.run();
132 join
133 #10 $finish;
134 end
135 endmodule
136