SV_16_interface

目录

1 Interface

2 Modports

2.1 Modport expression

2.2 Clocking blocks in modports

3. Task and function in interface

4. Parameterized interface

5. Virtual 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
View Code

2 Modports

  • modport关键字表面方向是在莫亏内部声明的,modport用于限制接口内的接口访问;
  • modport可以有:
  1. input
  2. output
  3. inout
  4. ref
  • 下面一个内存控制器的例子声明了以下几个modport:
  1. memery
  2. system sid
  3. 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
View Code

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
View Code

2.2 Clocking blocks in modports

  • modport也可以用来指定接口中声明的时钟块的方向;
  • 时钟块只对编写测试平台有用,对RTL没有用处;
  • 当与虚拟接口和实际接口一起使用时,时钟被用于同步信号;
  • 使用时应注意以下几点:
  1. 时钟块应该由与modport本身相同的接口来声明;
  2. 时钟信号的方向是从使用它的模块看到的方向;
  3. 读取inout总是产生最后的采样值,而不是驱动值(Reading the inout always yields the last sampled value, and not the driven value.);
  4. 当多个同步驱动应用到同一个时钟块时,会出现运行错误,并且冲突点会被驱动到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
View Code

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
View Code

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
View Code

5. Virtual interface

  • 在SV中可以使用虚拟接口将抽象模型和测试程序从组成设计的实际信号中分离出来;
  • 通过抽象块中的连接和函数实现了代码的重用;
  • 虚接口的特性:
  1. 虚拟接口可以像其他数据类型一样传递给任务和函数;
  2. 虚拟接口在使用时需要 进行初始化;
  3. 虚拟接口初始化前的缺省值为null;
  4. 虚拟的组件只能用于过程赋值,不能用于连续赋值;
  5. 在虚拟接口中驱动网络数据类型应该通过时钟来完成;
  6. 虚拟接口可以声明为诶属性,可以通过程序方式初始化,也可以通过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
View Code
  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
View Code
  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
View Code
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值