目录
2.2 Clocking blocks in modports
3. Task and function in interface
摘要:SV最后的特性之一就是interface,interface将端口进行绑定并作为一个单个项目保存,并允许在设计中被实例化,极大地提高了可维护性。
1 Interface
接口还包含任务和函数。为了方便主从支持(一个的输入是另一个的输出),接口包含了modport。
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Define the interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 interface mem_if (input wire clk);
5 wire reset;
6 wire we;
7 wire ce;
8 wire [7:0] datai;
9 logic [7:0] datao;
10 wire [7:0] addr;
11 //=================================================
12 // Clocking block for testbench
13 //=================================================
14 clocking cb @ (posedge clk);
15 output reset, we, ce, datai,addr;
16 input datao;
17 endclocking
18 //=================================================
19 // Modport for testbench
20 //=================================================
21 modport tb (clocking cb, input clk);
22
23 endinterface
24
25 //+++++++++++++++++++++++++++++++++++++++++++++++++
26 // DUT With interface
27 //+++++++++++++++++++++++++++++++++++++++++++++++++
28 module simple_if (mem_if mif);
29 // Memory array
30 logic [7:0] mem [0:255];
31
32 //=================================================
33 // Read logic
34 //=================================================
35 always @ (posedge mif.clk)
36 if (mif.reset) mif.datao <= 0;
37 else if (mif.ce && !mif.we) mif.datao <= mem[mif.addr];
38
39 //=================================================
40 // Write Logic
41 //=================================================
42 always @ (posedge mif.clk)
43 if (mif.ce && mif.we) mem[mif.addr] <= mif.datai;
44
45 endmodule
46
47 //+++++++++++++++++++++++++++++++++++++++++++++++++
48 // Testbench
49 //+++++++++++++++++++++++++++++++++++++++++++++++++
50 module tb();
51
52 logic clk = 0;
53 always #10 clk++;
54 //=================================================
55 // Instianciate Interface and DUT
56 //=================================================
57 mem_if miff(clk);
58 simple_if U_dut(miff);
59 //=================================================
60 // Default clocking
61 //=================================================
62 default clocking dclk @ (posedge clk);
63
64 endclocking
65 //=================================================
66 // Test Vector generation
67 //=================================================
68 initial begin
69 miff.tb.cb.reset <= 1;
70 miff.tb.cb.ce <= 1'b0;
71 miff.tb.cb.we <= 1'b0;
72 miff.tb.cb.addr <= 0;
73 miff.tb.cb.datai <= 0;
74 ##1 miff.tb.cb.reset <= 0;
75 for (int i = 0; i < 3; i ++ ) begin
76 ##1 miff.tb.cb.ce <= 1'b1;
77 miff.tb.cb.we <= 1'b1;
78 miff.tb.cb.addr <= i;
79 miff.tb.cb.datai <= $random;
80 ##3 miff.tb.cb.ce <= 1'b0;
81 $display ("@%0dns Write access address %x, data %x",
82 $time,miff.addr,miff.datai);
83 end
84 for (int i = 0; i < 3; i ++ ) begin
85 ##1 miff.tb.cb.ce <= 1'b1;
86 miff.tb.cb.we <= 1'b0;
87 miff.tb.cb.addr <= i;
88 ##3 miff.tb.cb.ce <= 1'b0;
89 $display ("@%0dns Read access address %x, data %x",
90 $time,miff.addr,miff.datao);
91 end
92 #10 $finish;
93 end
94
95 endmodule
96
97 //compile result
98
99 @90ns Write access address 00, data 24
100 @170ns Write access address 01, data 81
101 @250ns Write access address 02, data 09
102 @330ns Read access address 00, data 24
103 @410ns Read access address 01, data 81
104 @490ns Read access address 02, data 09
2 Modports
- modport关键字表面方向是在莫亏内部声明的,modport用于限制接口内的接口访问;
- modport可以有:
- input
- output
- inout
- ref
- 下面一个内存控制器的例子声明了以下几个modport:
- memery
- system sid
- testbench
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Define the interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 interface mem_if (input wire clk);
5 logic reset;
6 logic we_sys;
7 logic cmd_valid_sys;
8 logic ready_sys;
9 logic [7:0] data_sys;
10 logic [7:0] addr_sys;
11 logic we_mem;
12 logic ce_mem;
13 logic [7:0] datao_mem;
14 logic [7:0] datai_mem;
15 logic [7:0] addr_mem;
16 //=================================================
17 // Modport for System interface
18 //=================================================
19 modport system (input clk,reset,we_sys, cmd_valid_sys,
20 addr_sys, datao_mem,
21 output we_mem, ce_mem, addr_mem,
22 datai_mem, ready_sys, ref data_sys);
23 //=================================================
24 // Modport for memory interface
25 //=================================================
26 modport memory (input clk,reset,we_mem, ce_mem,
27 addr_mem, datai_mem, output datao_mem);
28 //=================================================
29 // Modport for testbench
30 //=================================================
31 modport tb (input clk, ready_sys,
32 output reset,we_sys, cmd_valid_sys, addr_sys,
33 ref data_sys);
34
35 endinterface
36
37 //+++++++++++++++++++++++++++++++++++++++++++++++++
38 // Memory Model
39 //+++++++++++++++++++++++++++++++++++++++++++++++++
40 module memory_model (mem_if.memory mif);
41 // Memory array
42 logic [7:0] mem [0:255];
43
44 //=================================================
45 // Write Logic
46 //=================================================
47 always @ (posedge mif.clk)
48 if (mif.ce_mem && mif.we_mem) begin
49 mem[mif.addr_mem] <= mif.datai_mem;
50 end
51
52 //=================================================
53 // Read Logic
54 //=================================================
55 always @ (posedge mif.clk)
56 if (mif.ce_mem && ~mif.we_mem) begin
57 mif.datao_mem <= mem[mif.addr_mem];
58 end
59
60 endmodule
61
62 //+++++++++++++++++++++++++++++++++++++++++++++++++
63 // Memory Controller
64 //+++++++++++++++++++++++++++++++++++++++++++++++++
65 module memory_ctrl (mem_if.system sif);
66
67 typedef enum {IDLE,WRITE,READ,DONE} fsm_t;
68
69 fsm_t state;
70
71 always @ (posedge sif.clk)
72 if (sif.reset) begin
73 state <= IDLE;
74 sif.ready_sys <= 0;
75 sif.we_mem <= 0;
76 sif.ce_mem <= 0;
77 sif.addr_mem <= 0;
78 sif.datai_mem <= 0;
79 sif.data_sys <= 8'bz;
80 end else begin
81 case(state)
82 IDLE : begin
83 sif.ready_sys <= 1'b0;
84 if (sif.cmd_valid_sys && sif.we_sys) begin
85 sif.addr_mem <= sif.addr_sys;
86 sif.datai_mem <= sif.data_sys;
87 sif.we_mem <= 1'b1;
88 sif.ce_mem <= 1'b1;
89 state <= WRITE;
90 end
91 if (sif.cmd_valid_sys && ~sif.we_sys) begin
92 sif.addr_mem <= sif.addr_sys;
93 sif.datai_mem <= sif.data_sys;
94 sif.we_mem <= 1'b0;
95 sif.ce_mem <= 1'b1;
96 state <= READ;
97 end
98 end
99 WRITE : begin
100 sif.ready_sys <= 1'b1;
101 if (~sif.cmd_valid_sys) begin
102 sif.addr_mem <= 8'b0;
103 sif.datai_mem <= 8'b0;
104 sif.we_mem <= 1'b0;
105 sif.ce_mem <= 1'b0;
106 state <= IDLE;
107 end
108 end
109 READ : begin
110 sif.ready_sys <= 1'b1;
111 sif.data_sys <= sif.datao_mem;
112 if (~sif.cmd_valid_sys) begin
113 sif.addr_mem <= 8'b0;
114 sif.datai_mem <= 8'b0;
115 sif.we_mem <= 1'b0;
116 sif.ce_mem <= 1'b0;
117 sif.ready_sys <= 1'b1;
118 state <= IDLE;
119 sif.data_sys <= 8'bz;
120 end
121 end
122 endcase
123 end
124
125 endmodule
126
127 //+++++++++++++++++++++++++++++++++++++++++++++++++
128 // Test program
129 //+++++++++++++++++++++++++++++++++++++++++++++++++
130 program test(mem_if.tb tif);
131
132 initial begin
133 tif.reset <= 1;
134 tif.we_sys <= 0;
135 tif.cmd_valid_sys <= 0;
136 tif.addr_sys <= 0;
137 tif.data_sys <= 8'bz;
138 #100 tif.reset <= 0;
139 for (int i = 0; i < 4; i ++) begin
140 @ (posedge tif.clk);
141 tif.addr_sys <= i;
142 tif.data_sys <= $random;
143 tif.cmd_valid_sys <= 1;
144 tif.we_sys <= 1;
145 @ (posedge tif.ready_sys);
146 $display("@%0dns Writing address %0d with data %0x",
147 $time, i,tif.data_sys);
148 @ (posedge tif.clk);
149 tif.addr_sys <= 0;
150 tif.data_sys <= 8'bz;
151 tif.cmd_valid_sys <= 0;
152 tif.we_sys <= 0;
153 end
154 repeat (10) @ (posedge tif.clk);
155 for (int i= 0; i < 4; i ++) begin
156 @ (posedge tif.clk);
157 tif.addr_sys <= i;
158 tif.cmd_valid_sys <= 1;
159 tif.we_sys <= 0;
160 @ (posedge tif.ready_sys);
161 @ (posedge tif.clk);
162 $display("@%0dns Reading address %0d, Got data %0x",
163 $time, i,tif.data_sys);
164 tif.addr_sys <= 0;
165 tif.cmd_valid_sys <= 0;
166 end
167 #10 $finish;
168 end
169
170 endprogram
171
172 //+++++++++++++++++++++++++++++++++++++++++++++++++
173 // Testbench
174 //+++++++++++++++++++++++++++++++++++++++++++++++++
175 module interface_modports();
176
177 logic clk = 0;
178 always #10 clk++;
179 //=================================================
180 // Instianciate Interface and DUT
181 //=================================================
182 mem_if miff(clk);
183 memory_ctrl U_ctrl(miff);
184 memory_model U_model(miff);
185 test U_test(miff);
186
187 endmodule
188
189 //compile result
190
191 @150ns Writing address 0 with data 24
192 @230ns Writing address 1 with data 81
193 @310ns Writing address 2 with data 9
194 @390ns Writing address 3 with data 63
195 @690ns Reading address 0, Got data 24
196 @770ns Reading address 1, Got data 81
197 @850ns Reading address 2, Got data 9
198 @930ns Reading address 3, Got data 63
2.1 Modport expression
- modoport表达式允许在modport列表中包含数组和结构的元素、连接的元素、以及 已在接口中声明的元素的赋值表达式;
- 接口表达式被显式地命名为一个端口标识符,仅通过modport连接可见。
- 使用modport expression最好的方法之一就是使用genvar使接口参数化。
- genvar:声明一个正整数变量(常用在generate);
1 // TODO : Complete this example
2 //+++++++++++++++++++++++++++++++++++++++++++++++++
3 // Define the interface
4 //+++++++++++++++++++++++++++++++++++++++++++++++++
5 interface arb_if #(num_agents = 1) (input clk);
6 logic reset;
7 logic [num_agents-1 : 0] req;
8 logic [num_agents-1 : 0] gnt;
9 //=================================================
10 // Modport inside a generate block
11 //=================================================
12 for (genvar i=0; i< num_agents; i++) begin: arb
13 modport arb (input .creq (req[i], clk, reset, output .cgnt (gnt[i]) );
14 modport tb (output .creq (req[i], input clk, reset, .cgnt (gnt[i]) );
15 end
16
17 endinterface
18
19 //+++++++++++++++++++++++++++++++++++++++++++++++++
20 // Testbench Top file
21 //+++++++++++++++++++++++++++++++++++++++++++++++++
22 module interface_modport_expression();
23
24 logic clk = 0;
25 always #1 clk ++;
26
27 arb_if arbif(clk);
28
29 initial begin
30 #100 $finish;
31 end
32
33 endmodule
2.2 Clocking blocks in modports
- modport也可以用来指定接口中声明的时钟块的方向;
- 时钟块只对编写测试平台有用,对RTL没有用处;
- 当与虚拟接口和实际接口一起使用时,时钟被用于同步信号;
- 使用时应注意以下几点:
- 时钟块应该由与modport本身相同的接口来声明;
- 时钟信号的方向是从使用它的模块看到的方向;
- 读取inout总是产生最后的采样值,而不是驱动值(Reading the inout always yields the last sampled value, and not the driven value.);
- 当多个同步驱动应用到同一个时钟块时,会出现运行错误,并且冲突点会被驱动到x;
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Define the interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 interface mem_if (input wire clk);
5 logic reset;
6 logic we_sys;
7 logic cmd_valid_sys;
8 logic ready_sys;
9 logic [7:0] data_sys;
10 logic [7:0] addr_sys;
11 logic we_mem;
12 logic ce_mem;
13 logic [7:0] datao_mem;
14 logic [7:0] datai_mem;
15 logic [7:0] addr_mem;
16 //=================================================
17 // Modport for System interface
18 //=================================================
19 modport system (input clk,reset,we_sys, cmd_valid_sys,
20 addr_sys, datao_mem,
21 output we_mem, ce_mem, addr_mem,
22 datai_mem, ready_sys, inout data_sys);
23 //=================================================
24 // Modport for memory interface
25 //=================================================
26 modport memory (input clk,reset,we_mem, ce_mem,
27 addr_mem, datai_mem, output datao_mem);
28 //=================================================
29 // Clockin in Modport for testbench
30 //=================================================
31 clocking cb @ (posedge clk);
32 input ready_sys;
33 output reset,we_sys, cmd_valid_sys, addr_sys;
34 inout data_sys;
35 endclocking
36 //=================================================
37 // Modport for testbench
38 //=================================================
39 modport tb (input clk, clocking cb);
40
41 endinterface
42
43 //+++++++++++++++++++++++++++++++++++++++++++++++++
44 // Memory Model
45 //+++++++++++++++++++++++++++++++++++++++++++++++++
46 module memory_model (mem_if.memory mif);
47 // Memory array
48 logic [7:0] mem [0:255];
49
50 //=================================================
51 // Write Logic
52 //=================================================
53 always @ (posedge mif.clk)
54 if (mif.ce_mem && mif.we_mem) begin
55 mem[mif.addr_mem] <= mif.datai_mem;
56 end
57
58 //=================================================
59 // Read Logic
60 //=================================================
61 always @ (posedge mif.clk)
62 if (mif.ce_mem && ~mif.we_mem) begin
63 mif.datao_mem <= mem[mif.addr_mem];
64 end
65
66 endmodule
67
68 //+++++++++++++++++++++++++++++++++++++++++++++++++
69 // Memory Controller
70 //+++++++++++++++++++++++++++++++++++++++++++++++++
71 module memory_ctrl (mem_if.system sif);
72
73 typedef enum {IDLE,WRITE,READ,DONE} fsm_t;
74
75 fsm_t state;
76
77 always @ (posedge sif.clk)
78 if (sif.reset) begin
79 state <= IDLE;
80 sif.ready_sys <= 0;
81 sif.we_mem <= 0;
82 sif.ce_mem <= 0;
83 sif.addr_mem <= 0;
84 sif.datai_mem <= 0;
85 sif.data_sys <= 8'bz;
86 end else begin
87 case(state)
88 IDLE : begin
89 sif.ready_sys <= 1'b0;
90 if (sif.cmd_valid_sys && sif.we_sys) begin
91 sif.addr_mem <= sif.addr_sys;
92 sif.datai_mem <= sif.data_sys;
93 sif.we_mem <= 1'b1;
94 sif.ce_mem <= 1'b1;
95 state <= WRITE;
96 end
97 if (sif.cmd_valid_sys && ~sif.we_sys) begin
98 sif.addr_mem <= sif.addr_sys;
99 sif.datai_mem <= sif.data_sys;
100 sif.we_mem <= 1'b0;
101 sif.ce_mem <= 1'b1;
102 state <= READ;
103 end
104 end
105 WRITE : begin
106 sif.ready_sys <= 1'b1;
107 if (~sif.cmd_valid_sys) begin
108 sif.addr_mem <= 8'b0;
109 sif.datai_mem <= 8'b0;
110 sif.we_mem <= 1'b0;
111 sif.ce_mem <= 1'b0;
112 state <= IDLE;
113 end
114 end
115 READ : begin
116 sif.ready_sys <= 1'b1;
117 sif.data_sys <= sif.datao_mem;
118 if (~sif.cmd_valid_sys) begin
119 sif.addr_mem <= 8'b0;
120 sif.datai_mem <= 8'b0;
121 sif.we_mem <= 1'b0;
122 sif.ce_mem <= 1'b0;
123 sif.ready_sys <= 1'b1;
124 state <= IDLE;
125 sif.data_sys <= 8'bz;
126 end
127 end
128 endcase
129 end
130
131 endmodule
132
133 //+++++++++++++++++++++++++++++++++++++++++++++++++
134 // Test program
135 //+++++++++++++++++++++++++++++++++++++++++++++++++
136 program test(mem_if.tb tif);
137
138 initial begin
139 tif.cb.reset <= 1;
140 tif.cb.we_sys <= 0;
141 tif.cb.cmd_valid_sys <= 0;
142 tif.cb.addr_sys <= 0;
143 tif.cb.data_sys <= 8'bz;
144 #100 tif.cb.reset <= 0;
145 for (int i = 0; i < 4; i ++) begin
146 @ (posedge tif.clk);
147 tif.cb.addr_sys <= i;
148 tif.cb.data_sys <= $random;
149 tif.cb.cmd_valid_sys <= 1;
150 tif.cb.we_sys <= 1;
151 @ (posedge tif.cb.ready_sys);
152 $display("@%0dns Writing address %0d with data %0x",
153 $time, i,tif.cb.data_sys);
154 @ (posedge tif.clk);
155 tif.cb.addr_sys <= 0;
156 tif.cb.data_sys <= 8'bz;
157 tif.cb.cmd_valid_sys <= 0;
158 tif.cb.we_sys <= 0;
159 end
160 repeat (10) @ (posedge tif.clk);
161 for (int i= 0; i < 4; i ++) begin
162 @ (posedge tif.clk);
163 tif.cb.addr_sys <= i;
164 tif.cb.cmd_valid_sys <= 1;
165 tif.cb.we_sys <= 0;
166 @ (posedge tif.cb.ready_sys);
167 @ (posedge tif.clk);
168 $display("@%0dns Reading address %0d, Got data %0x",
169 $time, i,tif.cb.data_sys);
170 tif.cb.addr_sys <= 0;
171 tif.cb.cmd_valid_sys <= 0;
172 end
173 #10 $finish;
174 end
175
176 endprogram
177
178 //+++++++++++++++++++++++++++++++++++++++++++++++++
179 // Testbench
180 //+++++++++++++++++++++++++++++++++++++++++++++++++
181 module interface_clocking_modports();
182
183 logic clk = 0;
184 always #10 clk++;
185 //=================================================
186 // Instianciate Interface and DUT
187 //=================================================
188 mem_if miff(clk);
189 memory_ctrl U_ctrl(miff);
190 memory_model U_model(miff);
191 test U_test(miff);
192
193 endmodule
194
195 //compile result
196
197 @190ns Writing address 0 with data 24
198 @310ns Writing address 1 with data 81
199 @430ns Writing address 2 with data 9
200 @550ns Writing address 3 with data 63
201 @890ns Reading address 0, Got data 24
202 @1010ns Reading address 1, Got data 81
203 @1130ns Reading address 2, Got data 9
204 @1250ns Reading address 3, Got data 63
3. Task and function in interface
- 接口也可以包含 task 和 function ,也可以在 接口外部或者内部;
- 如果 task 和 function 定义在模块中,使用层次结构名称,他们也必须在接口中声明为 extern 或在modport 中声明为export;
- 多个模块的任务名不可以重复;
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Define the interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 interface task_function_if (input clk);
5 logic req;
6 logic gnt;
7 //=================================================
8 // Clocking block for tb modport
9 //=================================================
10 clocking cb @ (posedge clk);
11 input gnt;
12 output req;
13 endclocking
14 //=================================================
15 // Task inside a interface, You can basically
16 // Write a BFM, who's input can be a class or
17 // a mailbox, so on..... SO COOL!!!!
18 //=================================================
19 task drive_req (input integer delay, input bit value);
20 $display("@%0dns Before driving req %b from task at %m", $time, req);
21 repeat (delay) @ (posedge clk);
22 req = value;
23 $display("@%0dns Driving req %b from task at %m", $time, req);
24 endtask
25 //=================================================
26 // Mod port with exporting and importing tasks
27 //=================================================
28 modport dut (input clk,req, output gnt
29 //, export print_md, import print_tb
30 );
31 //=================================================
32 // Mod Port with exporting and importing tasks
33 //=================================================
34 modport tb (clocking cb, input clk,
35 import drive_req
36 //, print_md, export print_tb
37 );
38
39 endinterface
40 //+++++++++++++++++++++++++++++++++++++++++++++++++
41 // DUT Code
42 // Uses just the interface keyword
43 //+++++++++++++++++++++++++++++++++++++++++++++++++
44 module dut_ex (interface abc);
45 //=================================================
46 // Task print_md, which is exported
47 //=================================================
48 //task abc.print_md (input logic something);
49 // $display("@%0dns Inside %m : From print_md", $time);
50 // $display("Value of req %b gnt %b in %m",abc.req, abc.gnt);
51 //endtask
52 //=================================================
53 // Simple DUT Logic and calling task in another
54 // Module through interface
55 //=================================================
56 always @ (posedge abc.clk)
57 begin
58 abc.gnt <= abc.req;
59 $display("@%0dns Request is %b", $time, abc.req);
60 if (abc.req === 1'bx) begin
61 //abc.print_tb(1'bx);
62 end
63 if (abc.req === 1'b0) begin
64 //abc.print_tb(1'b0);
65 end
66 if (abc.req === 1'b1) begin
67 //abc.print_tb(1'b1);
68 end
69 end
70
71 endmodule
72
73 //+++++++++++++++++++++++++++++++++++++++++++++++++
74 // TB Code
75 // Uses just the interface keyword
76 //+++++++++++++++++++++++++++++++++++++++++++++++++
77 module tb_ex (interface xyz);
78 //=================================================
79 // Task print_tb, which is exported
80 //=================================================
81 //task xyz.print_tb (input bit something);
82 // $display("@%0dns %m Value of req : %b", $time, something);
83 //endtask
84 //=================================================
85 // Test vector generation with task in another
86 // Module and in interface calling
87 //=================================================
88 initial begin
89 xyz.cb.req <= 0;
90 xyz.drive_req(10,1);
91 xyz.drive_req(10,0);
92 //xyz.print_md(0);
93 #2 $finish;
94 end
95
96 endmodule
97 //+++++++++++++++++++++++++++++++++++++++++++++++++
98 // Top level testbench file
99 //+++++++++++++++++++++++++++++++++++++++++++++++++
100 module interface_task_function();
101 //=================================================
102 // Clock generator
103 //=================================================
104 logic clk = 0;
105 always #1 clk++;
106 //=================================================
107 // Interface instance
108 //=================================================
109 task_function_if tfif(clk);
110 //=================================================
111 // DUT and TB instance
112 //=================================================
113 dut_ex U_dut(tfif.dut);
114 tb_ex U_tb(tfif.tb);
115
116 endmodule
117
118 //compile result
119 @0ns Before driving req x from task at
120 interface_task_function.tfif.drive_req
121 @1ns Request is x
122 @3ns Request is 0
123 @5ns Request is 0
124 @7ns Request is 0
125 @9ns Request is 0
126 @11ns Request is 0
127 @13ns Request is 0
128 @15ns Request is 0
129 @17ns Request is 0
130 @19ns Driving req 1 from task at
131 interface_task_function.tfif.drive_req
132 @19ns Before driving req 1 from
133 task at interface_task_function.tfif.drive_req
134 @19ns Request is 1
135 @21ns Request is 1
136 @23ns Request is 1
137 @25ns Request is 1
138 @27ns Request is 1
139 @29ns Request is 1
140 @31ns Request is 1
141 @33ns Request is 1
142 @35ns Request is 1
143 @37ns Request is 1
144 @39ns Driving req 0 from task at
145 interface_task_function.tfif.drive_req
146 @39ns Request is 0
4. Parameterized interface
- 接口定义可以像模块定义一样利用参数和参数重定义。
- 模块和接口中使用的参数没有区别;
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Define the interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 interface count_if #(WIDTH = 4) (input clk);
5 logic reset;
6 logic enable;
7 logic [WIDTH-1 : 0] count;
8 //=================================================
9 // Modports declaration
10 //=================================================
11 modport dut (input clk, reset, enable, output count);
12 modport tb (input clk, count, output reset, enable, import monitor);
13 //=================================================
14 // Monitor Task
15 //=================================================
16 task monitor();
17 while (1) begin
18 @ (posedge clk);
19 if (enable) begin
20 $display ("@%0dns reset %b enable %b count %b",
21 $time, reset, enable, count);
22 end
23 end
24 endtask
25 endinterface
26 //+++++++++++++++++++++++++++++++++++++++++++++++++
27 // Counter DUT
28 //+++++++++++++++++++++++++++++++++++++++++++++++++
29 module counter #(WIDTH = 4) (count_if.dut dif);
30 //=================================================
31 // Dut implementation
32 //=================================================
33 always @ (posedge dif.clk)
34 if (dif.reset) begin
35 dif.count <= {WIDTH{1'b0}};
36 end else if (dif.enable) begin
37 dif.count ++;
38 end
39 endmodule
40 //+++++++++++++++++++++++++++++++++++++++++++++++++
41 // Program for counter (TB)
42 //+++++++++++++++++++++++++++++++++++++++++++++++++
43 program counterp #(WIDTH = 4) (count_if.tb tif);
44 //=================================================
45 // Default Clocking for using ##<n> delay
46 //=================================================
47 default clocking cb @ (posedge tif.clk);
48
49 endclocking
50 //=================================================
51 // Generate the test vector
52 //=================================================
53 initial begin
54 // Fork of the monitor
55 fork
56 tif.monitor();
57 join_none
58 tif.reset <= 1;
59 tif.enable <= 0;
60 ##10 tif.reset <= 0;
61 ##1 tif.enable <= 1;
62 ##10 tif.enable <= 0;
63 ##5 $finish;
64 end
65 endprogram
66 //+++++++++++++++++++++++++++++++++++++++++++++++++
67 // Top Level
68 //+++++++++++++++++++++++++++++++++++++++++++++++++
69 module interface_parameter();
70 localparam WIDTH = 5;
71 logic clk = 0;
72 always #1 clk ++;
73
74 count_if #(WIDTH) cif (clk);
75 counter #(.WIDTH(WIDTH)) dut (cif);
76 counterp #(WIDTH) tb (cif);
77
78 endmodule
79
80 //compile result
81
82 @23ns reset 0 enable 1 count 00001
83 @25ns reset 0 enable 1 count 00010
84 @27ns reset 0 enable 1 count 00011
85 @29ns reset 0 enable 1 count 00100
86 @31ns reset 0 enable 1 count 00101
87 @33ns reset 0 enable 1 count 00110
88 @35ns reset 0 enable 1 count 00111
89 @37ns reset 0 enable 1 count 01000
90 @39ns reset 0 enable 1 count 01001
91 @41ns reset 0 enable 1 count 01010
5. Virtual interface
- 在SV中可以使用虚拟接口将抽象模型和测试程序从组成设计的实际信号中分离出来;
- 通过抽象块中的连接和函数实现了代码的重用;
- 虚接口的特性:
- 虚拟接口可以像其他数据类型一样传递给任务和函数;
- 虚拟接口在使用时需要 进行初始化;
- 虚拟接口初始化前的缺省值为null;
- 虚拟的组件只能用于过程赋值,不能用于连续赋值;
- 在虚拟接口中驱动网络数据类型应该通过时钟来完成;
- 虚拟接口可以声明为诶属性,可以通过程序方式初始化,也可以通过new()的参数初始化。
虚拟接口用于testbench的编写
1 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // Declare memory interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 interface memory (input bit clk);
5 wire [7:0] addr;
6 wire [7:0] data_i;
7 wire [7:0] data_o;
8 wire rw;
9 wire ce;
10 //==============================================
11 // Define the DUT modport
12 //==============================================
13 modport dut (input addr, data_i, rw, ce, clk, output data_o);
14 //==============================================
15 // Define the Testbench Driver modport
16 //==============================================
17 modport tb (output addr, data_i, rw, ce, input data_o, clk);
18 //==============================================
19 // Define the Testbench Monitor modport
20 //==============================================
21 modport mon (input addr, data_i, rw, ce, clk, data_o);
22 endinterface
23 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 // Simple memory model
25 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
26 module ram(memory.dut mif);
27
28 reg [7:0] memr [0:255];
29 //==============================================
30 // Memory read operation
31 //==============================================
32 assign mif.data_o = (~mif.rw && mif.ce) ?
33 memr[mif.addr] : 8'b0;
34 //==============================================
35 // Memory write operation
36 //==============================================
37 always @ (posedge mif.clk)
38 if (mif.ce && mif.rw)
39 memr[mif.addr] = mif.data_i;
40
41 endmodule
42 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
43 // Top level of memory model
44 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
45 module ram_top(memory.dut mif0,memory.dut mif1,memory.dut mif2);
46
47 ram U_ram0(mif0);
48 ram U_ram1(mif1);
49 ram U_ram2(mif2);
50
51 endmodule
52 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53 // Memory top level with DUT and testbench
54 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55 module mem_tb();
56 logic clk = 0;
57 always #1 clk = ~clk;
58 //==============================================
59 // interface with clock connected
60 //==============================================
61 memory mem_if0(clk);
62 memory mem_if1(clk);
63 memory mem_if2(clk);
64 //==============================================
65 // Connect the DUT
66 //==============================================
67 ram_top U_ram_top(
68 .mif0(mem_if0.dut),
69 .mif1(mem_if1.dut),
70 .mif2(mem_if2.dut)
71 );
72 //==============================================
73 // Connect the testbench
74 //==============================================
75 test U_test(
76 .tbf0(mem_if0),
77 .tbf1(mem_if1),
78 .tbf2(mem_if2)
79 );
80 endmodule
81 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82 // Testbench top level program
83 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84 program test(memory tbf0,memory tbf1,memory tbf2);
85 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
86 // Driver class
87 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
88 class driver;
89 virtual memory.tb ports;
90 //==============================================
91 // Constructor
92 //==============================================
93 function new(virtual memory.tb ports);
94 this.ports = ports;
95 endfunction
96 //==============================================
97 // Test vector generation
98 //==============================================
99 task run_t();
100 integer i = 0;
101 for (i= 0; i < 4; i ++) begin
102 @ (posedge ports.clk);
103 $display("Writing address %0d with data %0d",i,i);
104 ports.addr = i;
105 ports.data_i = i;
106 ports.ce = 1;
107 ports.rw = 1;
108 @ (posedge ports.clk);
109 ports.addr = 0;
110 ports.data_i = 0;
111 ports.ce = 0;
112 ports.rw = 0;
113 end
114 for (i= 0; i < 4; i ++) begin
115 @ (posedge ports.clk);
116 $display("Read address %0d",i);
117 ports.addr = i;
118 ports.data_i = i;
119 ports.ce = 1;
120 ports.rw = 0;
121 @ (posedge ports.clk);
122 ports.addr = 0;
123 ports.data_i = 0;
124 ports.ce = 0;
125 ports.rw = 0;
126 end
127 endtask
128 endclass
129 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
130 // Monitor class
131 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
132 class monitor;
133 reg [7:0] tbmem [255];
134 virtual memory.mon ports;
135 //==============================================
136 // Constructor
137 //==============================================
138 function new(virtual memory.mon ports);
139 this.ports = ports;
140 endfunction
141 //==============================================
142 // Monitor method
143 //==============================================
144 task run_t();
145 while(1) begin
146 @ (negedge ports.clk);
147 if (ports.ce) begin
148 if (ports.rw) begin
149 tbmem[ports.addr] = ports.data_i;
150 end else begin
151 if (ports.data_o != tbmem[ports.addr]) begin
152 $display("Error : Expected %0x Got %0x",
153 tbmem[ports.addr],ports.data_o);
154 end else begin
155 $display("Pass : Expected %0x Got %0x",
156 tbmem[ports.addr],ports.data_o);
157 end
158 end
159 end
160 end
161 endtask
162 endclass
163 //==============================================
164 // Initial block to start the testbench
165 //==============================================
166 initial begin
167 driver tb_driver0 = new(tbf0.tb);
168 monitor tb_monitor0 = new(tbf0.mon);
169 driver tb_driver1 = new(tbf1.tb);
170 monitor tb_monitor1 = new(tbf1.mon);
171 driver tb_driver2 = new(tbf2.tb);
172 monitor tb_monitor2 = new(tbf2.mon);
173 fork
174 begin
175 tb_monitor0.run_t();
176 end
177 begin
178 tb_monitor1.run_t();
179 end
180 begin
181 tb_monitor2.run_t();
182 end
183 join_none
184 fork
185 begin
186 tb_driver0.run_t();
187 end
188 begin
189 #100 tb_driver1.run_t();
190 end
191 begin
192 #200 tb_driver2.run_t();
193 end
194 join
195 #10 $finish;
196 end
197 endprogram
198
199 //compile result
200 Writing address 0 with data 0
201 Writing address 1 with data 1
202 Writing address 2 with data 2
203 Writing address 3 with data 3
204 Read address 0
205 Pass : Expected 0 Got 0
206 Read address 1
207 Pass : Expected 1 Got 1
208 Read address 2
209 Pass : Expected 2 Got 2
210 Read address 3
211 Pass : Expected 3 Got 3
212 Writing address 0 with data 0
213 Writing address 1 with data 1
214 Writing address 2 with data 2
215 Writing address 3 with data 3
216 Read address 0
217 Pass : Expected 0 Got 0
218 Read address 1
219 Pass : Expected 1 Got 1
220 Read address 2
221 Pass : Expected 2 Got 2
222 Read address 3
223 Pass : Expected 3 Got 3
224 Writing address 0 with data 0
225 Writing address 1 with data 1
226 Writing address 2 with data 2
227 Writing address 3 with data 3
228 Read address 0
229 Pass : Expected 0 Got 0
230 Read address 1
231 Pass : Expected 1 Got 1
232 Read address 2
233 Pass : Expected 2 Got 2
234 Read address 3
235 Pass : Expected 3 Got 3
1 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // Declare memory interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 interface memory (input bit clk);
5 wire [7:0] addr;
6 wire [7:0] data_i;
7 wire [7:0] data_o;
8 wire rw;
9 wire ce;
10 //==============================================
11 // Define the DUT modport
12 //==============================================
13 modport dut (input addr, data_i, rw, ce, clk, output data_o);
14 //==============================================
15 // Define the Testbench Driver modport
16 //==============================================
17 modport tb (output addr, data_i, rw, ce, input data_o, clk);
18 //==============================================
19 // Define the Testbench Monitor modport
20 //==============================================
21 modport mon (input addr, data_i, rw, ce, clk, data_o);
22 endinterface
23
24 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25 // Simple memory model
26 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27 module ram(memory.dut mif);
28
29 reg [7:0] memr [0:255];
30 //==============================================
31 // Memory read operation
32 //==============================================
33 assign mif.data_o = (~mif.rw && mif.ce) ?
34 memr[mif.addr] : 8'b0;
35 //==============================================
36 // Memory write operation
37 //==============================================
38 always @ (posedge mif.clk)
39 if (mif.ce && mif.rw)
40 memr[mif.addr] = mif.data_i;
41
42 endmodule
43 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44 // Top level of memory model
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 module ram_top(memory mif[1:3]);
47
48 ram U_ram0(mif[1].dut);
49 ram U_ram1(mif[2].dut);
50 ram U_ram2(mif[3].dut);
51
52 endmodule
53 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54 // Memory top level with DUT and testbench
55 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 module mem_tb();
57 logic clk = 0;
58 always #1 clk = ~clk;
59 //==============================================
60 // interface with clock connected
61 //==============================================
62 memory mem_if[1:3](clk);
63 //==============================================
64 // Connect the DUT
65 //==============================================
66 ram_top U_ram_top(
67 .mif(mem_if)
68 );
69 //==============================================
70 // Connect the testbench
71 //==============================================
72 test U_test(
73 .tbf(mem_if)
74 );
75
76 endmodule
77 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
78 // Testbench top level program
79 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
80 program test(memory tbf[1:3]);
81 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
82 // Driver class
83 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
84 class driver;
85 virtual memory.tb ports;
86 //==============================================
87 // Constructor
88 //==============================================
89 function new(virtual memory.tb ports);
90 this.ports = ports;
91 endfunction
92 //==============================================
93 // Test vector generation
94 //==============================================
95 task run_t();
96 integer i = 0;
97 for (i= 0; i < 4; i ++) begin
98 @ (posedge ports.clk);
99 $display("Writing address %0d with data %0d",i,i);
100 ports.addr = i;
101 ports.data_i = i;
102 ports.ce = 1;
103 ports.rw = 1;
104 @ (posedge ports.clk);
105 ports.addr = 0;
106 ports.data_i = 0;
107 ports.ce = 0;
108 ports.rw = 0;
109 end
110 for (i= 0; i < 4; i ++) begin
111 @ (posedge ports.clk);
112 $display("Read address %0d",i);
113 ports.addr = i;
114 ports.data_i = i;
115 ports.ce = 1;
116 ports.rw = 0;
117 @ (posedge ports.clk);
118 ports.addr = 0;
119 ports.data_i = 0;
120 ports.ce = 0;
121 ports.rw = 0;
122 end
123 endtask
124 endclass
125 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
126 // Monitor class
127 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
128 class monitor;
129 reg [7:0] tbmem [255];
130 virtual memory.mon ports;
131 //==============================================
132 // Constructor
133 //==============================================
134 function new(virtual memory.mon ports);
135 this.ports = ports;
136 endfunction
137 //==============================================
138 // Monitor method
139 //==============================================
140 task run_t();
141 while(1) begin
142 @ (negedge ports.clk);
143 if (ports.ce) begin
144 if (ports.rw) begin
145 tbmem[ports.addr] = ports.data_i;
146 end else begin
147 if (ports.data_o != tbmem[ports.addr]) begin
148 $display("Error : Expected %0x Got %0x",
149 tbmem[ports.addr],ports.data_o);
150 end else begin
151 $display("Pass : Expected %0x Got %0x",
152 tbmem[ports.addr],ports.data_o);
153 end
154 end
155 end
156 end
157 endtask
158 endclass
159 //==============================================
160 // Initial block to start the testbench
161 //==============================================
162 initial begin
163 driver tb_driver0 = new(tbf[1].tb);
164 monitor tb_monitor0 = new(tbf[1].mon);
165 driver tb_driver1 = new(tbf[2].tb);
166 monitor tb_monitor1 = new(tbf[2].mon);
167 driver tb_driver2 = new(tbf[3].tb);
168 monitor tb_monitor2 = new(tbf[3].mon);
169 fork
170 begin
171 tb_monitor0.run_t();
172 end
173 begin
174 tb_monitor1.run_t();
175 end
176 begin
177 tb_monitor2.run_t();
178 end
179 join_none
180 fork
181 begin
182 tb_driver0.run_t();
183 end
184 begin
185 #100 tb_driver1.run_t();
186 end
187 begin
188 #200 tb_driver2.run_t();
189 end
190 join
191 #10 $finish;
192 end
193 endprogram
194
195 //compile result
196
197 Writing address 0 with data 0
198 Writing address 1 with data 1
199 Writing address 2 with data 2
200 Writing address 3 with data 3
201 Read address 0
202 Pass : Expected 0 Got 0
203 Read address 1
204 Pass : Expected 1 Got 1
205 Read address 2
206 Pass : Expected 2 Got 2
207 Read address 3
208 Pass : Expected 3 Got 3
209 Writing address 0 with data 0
210 Writing address 1 with data 1
211 Writing address 2 with data 2
212 Writing address 3 with data 3
213 Read address 0
214 Pass : Expected 0 Got 0
215 Read address 1
216 Pass : Expected 1 Got 1
217 Read address 2
218 Pass : Expected 2 Got 2
219 Read address 3
220 Pass : Expected 3 Got 3
221 Writing address 0 with data 0
222 Writing address 1 with data 1
223 Writing address 2 with data 2
224 Writing address 3 with data 3
225 Read address 0
226 Pass : Expected 0 Got 0
227 Read address 1
228 Pass : Expected 1 Got 1
229 Read address 2
230 Pass : Expected 2 Got 2
231 Read address 3
232 Pass : Expected 3 Got 3
1 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // Declare memory interface
3 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 interface memory (input bit clk);
5 wire [7:0] addr;
6 wire [7:0] data_i;
7 wire [7:0] data_o;
8 wire rw;
9 wire ce;
10 //==============================================
11 // Define the DUT modport
12 //==============================================
13 modport dut (input addr, data_i, rw, ce, clk, output data_o);
14 //==============================================
15 // Define the Testbench Driver modport
16 //==============================================
17 modport tb (output addr, data_i, rw, ce, input data_o, clk);
18 //==============================================
19 // Define the Testbench Monitor modport
20 //==============================================
21 modport mon (input addr, data_i, rw, ce, clk, data_o);
22
23 endinterface
24 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25 // Simple memory model
26 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27 module ram(memory.dut mif);
28
29 reg [7:0] memr [0:255];
30 //==============================================
31 // Memory read operation
32 //==============================================
33 assign mif.data_o = (~mif.rw && mif.ce) ?
34 memr[mif.addr] : 8'b0;
35 //==============================================
36 // Memory write operation
37 //==============================================
38 always @ (posedge mif.clk)
39 if (mif.ce && mif.rw)
40 memr[mif.addr] = mif.data_i;
41
42 endmodule
43 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44 // Top level of memory model
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 module ram_top(memory mif[1:3]);
47
48 ram U_ram0(mif[1].dut);
49 ram U_ram1(mif[2].dut);
50 ram U_ram2(mif[3].dut);
51
52 endmodule
53 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54 // Memory top level with DUT and testbench
55 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
56 module mem_tb();
57 logic clk = 0;
58 always #1 clk = ~clk;
59 //==============================================
60 // interface with clock connected
61 //==============================================
62 memory mem_if[1:3](clk);
63 //==============================================
64 // Connect the DUT
65 //==============================================
66 ram_top U_ram_top(mem_if);
67 //==============================================
68 // Connect the testbench
69 //==============================================
70 test U_test(mem_if);
71 endmodule
72 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
73 // Testbench top level program
74 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
75 program test(memory tbf[1:3]);
76 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
77 // Driver class
78 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
79 class driver;
80 virtual memory.tb ports[1:3];
81 //==============================================
82 // Constructor
83 //==============================================
84 function new(virtual memory.tb ports[1:3]);
85 this.ports = ports;
86 endfunction
87 //==============================================
88 // Test vector generation
89 //==============================================
90 task run_t(integer portno);
91 integer i = 0;
92 for (i= 0; i < 4; i ++) begin
93 @ (posedge ports[portno].clk);
94 $display("Writing address %0d with data %0d",i,i);
95 ports[portno].addr = i;
96 ports[portno].data_i = i;
97 ports[portno].ce = 1;
98 ports[portno].rw = 1;
99 @ (posedge ports[portno].clk);
100 ports[portno].addr = 0;
101 ports[portno].data_i = 0;
102 ports[portno].ce = 0;
103 ports[portno].rw = 0;
104 end
105 for (i= 0; i < 4; i ++) begin
106 @ (posedge ports[portno].clk);
107 $display("Read address %0d",i);
108 ports[portno].addr = i;
109 ports[portno].data_i = i;
110 ports[portno].ce = 1;
111 ports[portno].rw = 0;
112 @ (posedge ports[portno].clk);
113 ports[portno].addr = 0;
114 ports[portno].data_i = 0;
115 ports[portno].ce = 0;
116 ports[portno].rw = 0;
117 end
118 endtask
119 endclass
120 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
121 // Monitor class
122 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
123 class monitor;
124 reg [7:0] tbmem [255];
125 virtual memory.mon ports[1:3];
126 //==============================================
127 // Constructor
128 //==============================================
129 function new(virtual memory.mon ports[1:3]);
130 this.ports = ports;
131 endfunction
132 //==============================================
133 // Monitor method
134 //==============================================
135 task run_t(integer portno);
136 while(1) begin
137 @ (negedge ports[portno].clk);
138 if (ports[portno].ce) begin
139 if (ports[portno].rw) begin
140 tbmem[ports[portno].addr] = ports[portno].data_i;
141 end else begin
142 if (ports[portno].data_o != tbmem[ports[portno].addr]) begin
143 $display("Error : Expected %0x Got %0x",
144 tbmem[ports[portno].addr],ports[portno].data_o);
145 end else begin
146 $display("Pass : Expected %0x Got %0x",
147 tbmem[ports[portno].addr],ports[portno].data_o);
148 end
149 end
150 end
151 end
152 endtask
153 endclass
154 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
155 // Wrapper for monitor and driver
156 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
157 class tb_shell;
158 driver tb_driver ;
159 monitor tb_monitor ;
160 //==============================================
161 // Constructor
162 //==============================================
163 function new (virtual memory tbfl[1:3]);
164 tb_driver = new(tbfl);
165 tb_monitor = new(tbfl);
166 endfunction
167 //==============================================
168 // Method to fork of Monitor and Drivers
169 //==============================================
170 task run_t();
171 for (int portno = 1; portno <= 3; portno++) begin
172 automatic int portno_t = portno;
173 fork
174 tb_monitor.run_t(portno_t);
175 join_none
176 end
177 for (int portno = 1; portno <= 3; portno++) begin
178 automatic int portno_t = portno;
179 fork
180 tb_monitor.run_t(portno_t);
181 join_none
182 end
183 fork
184 begin
185 tb_driver.run_t(1);
186 end
187 begin
188 #100 tb_driver.run_t(2);
189 end
190 begin
191 #200 tb_driver.run_t(3);
192 end
193 join
194 endtask
195 endclass
196 //==============================================
197 // Initial block to start the testbench
198 //==============================================
199 initial begin
200 tb_shell shell = new(tbf);
201 shell.run_t();
202 #10 $finish;
203 end
204 endprogram
205
206 //compile result
207 Writing address 0 with data 0
208 Writing address 1 with data 1
209 Writing address 2 with data 2
210 Writing address 3 with data 3
211 Read address 0
212 Pass : Expected 0 Got 0
213 Pass : Expected 0 Got 0
214 Read address 1
215 Pass : Expected 1 Got 1
216 Pass : Expected 1 Got 1
217 Read address 2
218 Pass : Expected 2 Got 2
219 Pass : Expected 2 Got 2
220 Read address 3
221 Pass : Expected 3 Got 3
222 Pass : Expected 3 Got 3
223 Writing address 0 with data 0
224 Writing address 1 with data 1
225 Writing address 2 with data 2
226 Writing address 3 with data 3
227 Read address 0
228 Pass : Expected 0 Got 0
229 Pass : Expected 0 Got 0
230 Read address 1
231 Pass : Expected 1 Got 1
232 Pass : Expected 1 Got 1
233 Read address 2
234 Pass : Expected 2 Got 2
235 Pass : Expected 2 Got 2
236 Read address 3
237 Pass : Expected 3 Got 3
238 Pass : Expected 3 Got 3
239 Writing address 0 with data 0
240 Writing address 1 with data 1
241 Writing address 2 with data 2
242 Writing address 3 with data 3
243 Read address 0
244 Pass : Expected 0 Got 0
245 Pass : Expected 0 Got 0
246 Read address 1
247 Pass : Expected 1 Got 1
248 Pass : Expected 1 Got 1
249 Read address 2
250 Pass : Expected 2 Got 2
251 Pass : Expected 2 Got 2
252 Read address 3
253 Pass : Expected 3 Got 3
254 Pass : Expected 3 Got 3