首页 > 其他 > 详细

UVM Primer - 常规验证平台

时间:2020-02-26 18:45:30      阅读:45      评论:0      收藏:0      [点我收藏+]

所有的行为都混在一个文件中

module top;

   typedef enum bit[2:0] {no_op  = 3b000,
                          add_op = 3b001, 
                          and_op = 3b010,
                          xor_op = 3b011,
                          mul_op = 3b100,
                          rst_op = 3b111} operation_t;
   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;

   tinyalu DUT (.A, .B, .clk, .op, .reset_n, .start, .done, .result);


   //covergroup模块
   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




   initial begin
      clk = 0;
      forever begin
         #10;
         clk = ~clk;
      end
   end
   
   op_cov oc;
   zeros_or_ones_on_ops c_00_FF;

   initial begin : coverage
   
      oc = new();
      c_00_FF = new();
   
      forever begin @(negedge clk);
         oc.sample();
         c_00_FF.sample();
      end
   end : coverage
   

   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
//scoreboard自检
//Scoreboard循环会用预期结果来检查TinyALU的结果。循环会监控done信号,每当done信号拉高,scoreboard根据TinyALU的输入预测其结果,并检查其是否正确
always @(posedge done) begin : scoreboard shortint predicted_result; case (op_set) add_op: predicted_result = A + B; and_op: predicted_result = A & B; xor_op: predicted_result = A ^ B; mul_op: predicted_result = A * B; endcase // case (op_set) if ((op_set != no_op) && (op_set != rst_op)) if (predicted_result != result) $error ("FAILED: A: %0h B: %0h op: %s result: %0h", A, B, op_set.name(), result); end : scoreboard //tester模块 initial begin : tester reset_n = 1b0; @(negedge clk); @(negedge clk); reset_n = 1b1; start = 1b0; repeat (1000) begin @(negedge clk); op_set = get_op(); A = get_data(); B = get_data(); start = 1b1; case (op_set) // handle the start signal no_op: begin @(posedge clk); start = 1b0; end rst_op: begin reset_n = 1b0; start = 1b0; @(negedge clk); reset_n = 1b1; end default: begin wait(done); start = 1b0; end endcase // case (op_set) end $stop; end : tester endmodule : top

 

UVM Primer - 常规验证平台

原文:https://www.cnblogs.com/yiyedada/p/12367856.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!