请教systemverilog中的interface问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请教systemverilog中的interface问题相关的知识,希望对你有一定的参考价值。

参考技术A 普通的模块使用法:注意我们这里只实现了部分功能。。。。不是完全的读写模块。。。。
module mem_core(
input logic wen,
input logic ren,
output logic mrdy=1,
input logic [7:0] addr,
input logic [7:0] mem_din, //写进mem
output logic [7:0] mem_dout, //从mem读出
output logic status,
input logic clk);

logic[7:0] mem [7:0]; //初始化一个mem

initial $readmemh("d:/init.txt",mem); //d:/init.txt 文件中是 @01 10 。

//或者 assign mem [2'h01]=8'b00000111; 注意这里一定要用 initial 或者assign等语句,不能直接=

task reply_read(input logic [7:0] data, integer delay);
#delay;
@(negedge clk)
mrdy=1'b0;
mem_dout=data; //从图中可看出这两句话几乎同时执行。
@(negedge clk)
mrdy=1'b1;
endtask

always@(negedge ren) reply_read(mem[addr],10);
endmodule
module cpu_core(
output logic wen=1,
output logic ren=1,
input logic mrdy,
output logic [7:0] addr=0,
input logic [7:0] cpu_din,
output logic [7:0] cpu_dout,
output logic status=0,
input logic clk);
task read_memory(input logic [7:0] raddr, output logic [7:0] data);
@(posedge clk);
ren=1'b0;
addr=raddr;
@(negedge mrdy);
@(posedge clk);
data=cpu_din;
ren=1'b1;
endtask

initial begin
logic[7:0] read_data;
read_memory(2'h01, read_data);
$display("Read Result", $time,read_data);
end
endmodule
module top;
logic mrdy,wen,ren;
logic[7:0] addr,d1,d2;
wor status;
logic clk=0;
mem_core mem(.*, .mem_din(d1), .mem_dout(d2)); //采用*对同名的信号做默认连接
cpu_core cpu(.*, .cpu_din(d2), .cpu_dout(d1));
initial for(int i=0;i<=255;i++) #1 clk=!clk;
endmodule

另外,SystemVerilog引入一个重要的数据类型:interface。其主要作用有两个:一是简化模块之间的连接;二是实现类和模块之间的通信;
随着复杂度的提高,模块间互联变得复杂,SV引入接口,代表一捆连线的结构,具有智能同步和连接功能的代码;
接口(interface)为硬件模块的端口提供了一个标准化的封装方式。
用interface来封装接口的信号和功能。interface的定
义是独立于模块的,通过关键字interface和endinterface包起来。此外,interface里面还可以
带时钟、断言、方法等定义。
一个interface 也可以有input,output或是inout端口。当interface例化时,只有当变量或是线网声明在一个interface的端口列表中才能通过名字或是位置来互连.本回答被提问者采纳

UVM Primer - SystemVerilog interfaces 和 BFM

tinyalu_pkg.sv

package tinyalu_pkg;
      typedef enum bit[2:0] {no_op  = 3‘b000,
                          add_op = 3‘b001, 
                          and_op = 3‘b010,
                          xor_op = 3‘b011,
                          mul_op = 3‘b100,
                          rst_op = 3‘b111} operation_t;

endpackage : tinyalu_pkg

tinyalu_bfm.sv

interface tinyalu_bfm;
   import tinyalu_pkg::*;

   byte         unsigned        A;
   byte         unsigned        B;
   bit          clk;
   bit          reset_n;
   wire [2:0]   op;
   bit          start;
   wire         done;
   wire [15:0]  result;
   operation_t  op_set;

   assign op = op_set;

   initial begin
      clk = 0;
      forever begin
         #10;
         clk = ~clk;
      end
   end


   task reset_alu();
      reset_n = 1b0;
      @(negedge clk);
      @(negedge clk);
      reset_n = 1b1;
      start = 1b0;
   endtask : reset_alu
   
  task send_op(input byte iA, input byte iB, input operation_t iop, 
               output shortint alu_result);
     
     op_set = iop;
     
     if (iop == rst_op) begin
         @(posedge clk);
         reset_n = 1b0;
         start = 1b0;
         @(posedge clk);
         #1;
         reset_n = 1b1;
      end else begin
         @(negedge clk);
         A = iA;
         B = iB;
         start = 1b1;
         if (iop == no_op) begin
            @(posedge clk);
            #1;
            start = 1b0;           
         end else begin
            do
              @(negedge clk);
            while (done == 0);
            start = 1b0;
         end
      end // else: !if(iop == rst_op)
      
   endtask : send_op

endinterface : tinyalu_bfm

top.sv

module top;
   tinyalu_bfm    bfm();
   tester     tester_i    (bfm);
   coverage   coverage_i  (bfm);
   scoreboard scoreboard_i(bfm);
   
   tinyalu DUT (.A(bfm.A), .B(bfm.B), .op(bfm.op), 
                .clk(bfm.clk), .reset_n(bfm.reset_n), 
                .start(bfm.start), .done(bfm.done), .result(bfm.result));
endmodule : top

scoreboard.sv

module scoreboard(tinyalu_bfm bfm);
   import tinyalu_pkg::*;

   always @(posedge bfm.done) begin 
      shortint predicted_result;
      case (bfm.op_set)
        add_op: predicted_result = bfm.A + bfm.B;
        and_op: predicted_result = bfm.A & bfm.B;
        xor_op: predicted_result = bfm.A ^ bfm.B;
        mul_op: predicted_result = bfm.A * bfm.B;
      endcase // case (op_set)

      if ((bfm.op_set != no_op) && (bfm.op_set != rst_op))
        if (predicted_result != bfm.result)
          $error ("FAILED: A: %0h  B: %0h  op: %s result: %0h",
                  bfm.A, bfm.B, bfm.op_set.name(), bfm.result);

   end 
endmodule : scoreboard

tester.sv

module tester(tinyalu_bfm bfm);
   import tinyalu_pkg::*;

   function operation_t get_op();
      bit [2:0] op_choice;
      op_choice = $random;
      case (op_choice)
        3b000 : return no_op;
        3b001 : return add_op;
        3b010 : return and_op;
        3b011 : return xor_op;
        3b100 : return mul_op;
        3b101 : return no_op;
        3b110 : return rst_op;
        3b111 : return rst_op;
      endcase // case (op_choice)
   endfunction : get_op

   function byte get_data();
      bit [1:0] zero_ones;
      zero_ones = $random;
      if (zero_ones == 2b00)
        return 8h00;
      else if (zero_ones == 2b11)
        return 8hFF;
      else
        return $random;
   endfunction : get_data
   
   initial begin
      byte         unsigned        iA;
      byte         unsigned        iB;
      operation_t                  op_set;
      shortint     result;
      
      bfm.reset_alu();
      repeat (1000) begin : random_loop
         op_set = get_op();
         iA = get_data();
         iB = get_data();
         bfm.send_op(iA, iB, op_set, result);
      end : random_loop
      $stop;
   end // initial begin
endmodule : tester

coverage.sv

module coverage(tinyalu_bfm bfm);
  import tinyalu_pkg::*;

   byte         unsigned        A;
   byte         unsigned        B;
   operation_t  op_set;

   covergroup op_cov;

      coverpoint op_set {
         bins single_cycle[] = {[add_op : xor_op], rst_op,no_op};
         bins multi_cycle = {mul_op};

         bins opn_rst[] = ([add_op:no_op] => rst_op);
         bins rst_opn[] = (rst_op => [add_op:no_op]);

         bins sngl_mul[] = ([add_op:xor_op],no_op => mul_op);
         bins mul_sngl[] = (mul_op => [add_op:xor_op], no_op);

         bins twoops[] = ([add_op:no_op] [* 2]);
         bins manymult = (mul_op [* 3:5]);

      }

   endgroup

   covergroup zeros_or_ones_on_ops;

      all_ops : coverpoint op_set {
         ignore_bins null_ops = {rst_op, no_op};}

      a_leg: coverpoint A {
         bins zeros = {h00};
         bins others= {[h01:hFE]};
         bins ones  = {hFF};
      }

      b_leg: coverpoint B {
         bins zeros = {h00};
         bins others= {[h01:hFE]};
         bins ones  = {hFF};
      }

      op_00_FF:  cross a_leg, b_leg, all_ops {
         bins add_00 = binsof (all_ops) intersect {add_op} &&
                       (binsof (a_leg.zeros) || binsof (b_leg.zeros));

         bins add_FF = binsof (all_ops) intersect {add_op} &&
                       (binsof (a_leg.ones) || binsof (b_leg.ones));

         bins and_00 = binsof (all_ops) intersect {and_op} &&
                       (binsof (a_leg.zeros) || binsof (b_leg.zeros));

         bins and_FF = binsof (all_ops) intersect {and_op} &&
                       (binsof (a_leg.ones) || binsof (b_leg.ones));

         bins xor_00 = binsof (all_ops) intersect {xor_op} &&
                       (binsof (a_leg.zeros) || binsof (b_leg.zeros));

         bins xor_FF = binsof (all_ops) intersect {xor_op} &&
                       (binsof (a_leg.ones) || binsof (b_leg.ones));

         bins mul_00 = binsof (all_ops) intersect {mul_op} &&
                       (binsof (a_leg.zeros) || binsof (b_leg.zeros));

         bins mul_FF = binsof (all_ops) intersect {mul_op} &&
                       (binsof (a_leg.ones) || binsof (b_leg.ones));

         bins mul_max = binsof (all_ops) intersect {mul_op} &&
                        (binsof (a_leg.ones) && binsof (b_leg.ones));

         ignore_bins others_only =
                                  binsof(a_leg.others) && binsof(b_leg.others);

      }

endgroup

   op_cov oc;
   zeros_or_ones_on_ops c_00_FF;

   initial begin : coverage_block
      oc = new();
      c_00_FF = new();
      forever begin  : sampling_block
         @(negedge bfm.clk);
         A = bfm.A;
         B = bfm.B;
         op_set = bfm.op_set;
         oc.sample();
         c_00_FF.sample();
      end : sampling_block
   end : coverage_block
   
      
endmodule : coverage

 

以上是关于请教systemverilog中的interface问题的主要内容,如果未能解决你的问题,请参考以下文章

UVM Primer - SystemVerilog interfaces 和 BFM

浅析SystemVerilog之package

systemverilog学习基础

systemverilog接口

SystemVerilog 采样和数据驱动

请教JAVA中interface的作用