SV_16_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
浙公网安备 33010602011771号