【【简单systyem verilog 语言学习使用三--- 新新adder加法器-覆盖率测试】】

顶层文件 adder.v

c 复制代码
module  adder (
    input                    clk      ,
    input                    rst_n    ,
    input         [3 : 0]    in_0     ,
    input         [3 : 0]    in_1     ,
    input                    sel      ,   // 判断信号 
    output        [4 : 0]    out0     ,
    output        [4 : 0]    out1     ,
    output   reg  [4 : 0]    out2
  );

  always@(posedge clk or negedge rst_n )
  begin
    if(rst_n == 0)
    begin
      out2  <=  0    ;
    end
    else
    begin
      out2  <=  in_0 + in_1 ;
    end
  end


  assign  out1   = sel?  in_1 : 0  ;  
  assign  out0   = sel?  in_0 : 0  ; 

endmodule  

tb文件

c 复制代码
// 输入 常规class的定�? -- 仅仅为了好玩
class play;
  static int count = 0;
  int id;
  logic [2:0] ina;
  logic [5:0] func_a;
  int arr[6] = '{0, 1, 2, 3, 4, 5};

  // 构�?�函�?
  function new();
    this.id = count++;
  endfunction

  // 打印数组�?
  task showk();
    foreach (arr[i])
    begin
      int k = arr[i];
      $write("%d\n", k);
    end
  endtask

  // 功能函数
  function int shown_a(int a);
    func_a = a + a;
    $display("function shown_a number is %d", func_a);
    return func_a;
  endfunction
endclass

//------------------------------------------------
// Transaction 类定�?
class Transaction;
  rand bit [3:0] ina; // 输入信号a
  rand bit [3:0] inb; // 输入信号b
  rand bit sel;       // 选择信号

  function new();
    ina = 0;
    inb = 0;
    sel = 0;
  endfunction
endclass

// 定义覆盖�?
covergroup CovPort(ref Transaction tr, input logic [3:0] in_0, input logic [3:0] in_1);
  coverpoint tr.ina; // �?�? ina
  coverpoint tr.inb; // �?�? inb
  coverpoint tr.sel; // �?�? sel
  coverpoint in_0  ;
  coverpoint in_1  ;
endgroup

// 定义基类
virtual class driver_back;
          virtual task post_tx(ref Transaction tr, input logic [3:0] in_0, input logic [3:0] in_1);
                  endtask
                endclass

                // 扩展 driver_back,添加覆盖组逻辑
                class CoverageCallback extends driver_back;
                  CovPort cov;

                  // 构造函数,初始化覆盖组
                  function void init_cov(ref Transaction tr, input logic [3:0] in_0, input logic [3:0] in_1);
                    cov = new(tr,in_0,in_1);
                  endfunction

                  // 回调任务:触发采样
                  virtual task post_tx(ref Transaction tr, input logic [3:0] in_0, input logic [3:0] in_1);
                            cov.sample();  // 触发覆盖组采样
                            $display("Coverage sampled: ina=%0d, inb=%0d, sel=%0d", tr.ina, tr.inb, tr.sel);
                          endtask

                          // 打印单个点的覆盖率
                          function void report_coverage();
                            real coverage_in_0, coverage_in_1;

                            // 获取整个覆盖组的覆盖率
                            coverage_in_0 = cov.get_coverage();  // 获取整个CovPort的覆盖率
                            coverage_in_1 = cov.get_coverage();  // 可以重复同样的方式获取每个coverpoint的覆盖

                            // 打印覆盖率

                            $display("Coverage for in_0: %0.2f%%", coverage_in_0 );
                            $display("Coverage for in_1: %0.2f%%", coverage_in_1 );
                          endfunction
                        endclass
                        // 定义模块
                        module test();
                          // 端口定义
                          logic clk;
                          logic rst_n;
                          logic [3:0] in_0;
                          logic [3:0] in_1;
                          logic sel;         // 判断信号
                          logic [4:0] out0;
                          logic [4:0] out1;
                          logic [4:0] out2;
                          logic [5 : 0] result_b ;
                          logic [5 : 0] result_a ;
                          // 类定义
                          Transaction tr;
                          CoverageCallback cb;
                          play inst_a, inst_b;


                          // 时钟生成
                          initial
                          begin
                            clk = 0;
                            forever
                              #5 clk = ~clk;
                          end

                          // DUT(设备模块)
                          adder u_adder (
                                  .clk(clk),
                                  .rst_n(rst_n),
                                  .in_0(in_0),
                                  .in_1(in_1),
                                  .sel(sel),
                                  .out0(out0),
                                  .out1(out1),
                                  .out2(out2)
                                );

                          // 驱动 Transaction 信号到 DUT
                          always @(posedge clk or negedge rst_n)
                          begin
                            if (!rst_n)
                            begin
                              in_0 <= 0;
                              in_1 <= 0;
                              sel  <= 0;
                            end
                            else
                            begin
                              in_0 <= tr.ina;
                              in_1 <= tr.inb;
                              sel  <= tr.sel;
                            end
                          end

                          // 测试逻辑
                          initial
                          begin
                            rst_n = 0;
                            inst_a = new();
                            inst_b = new();
                            $display("inst_a id = %d", inst_a.id);
                            $display("inst_b id = %d", inst_b.id);

                            // 调用 showk 打印数组
                            inst_a.showk();
                            inst_b.showk();

                            // 调用 shown_a 进行测试
                            result_a = inst_a.shown_a(5); // 示例输入值为 5
                            $display("inst_a.shown_a(5) result = %d", result_a);

                            result_b = inst_b.shown_a(10); // 示例输入值为 10
                            $display("inst_b.shown_a(10) result = %d", result_b);

                            #20 rst_n = 1;

                            // 实例化 Transaction 和 CoverageCallback
                            tr = new();
                            cb = new();
                            cb.init_cov(tr,in_0,in_1);

                            // 随机化并进行覆盖率采样
                            repeat (10)
                            begin
                              assert(tr.randomize());
                              cb.post_tx(tr,in_0,in_1);  // 触发采样
                              #20;  // 增加延迟以等待 DUT 输出稳定
                              $display("DUT Outputs: out0=%0d, out1=%0d, out2=%0d", out0, out1, out2);
                            end

                            // 打印覆盖率报告
                            cb.report_coverage();

                          end
                        endmodule
相关推荐
两水先木示32 分钟前
【Unity3D】ECS入门学习(九)SystemBase
学习·unity·ecs
simple_ssn1 小时前
汇编学习笔记
汇编·笔记·学习
纪伊路上盛名在2 小时前
NCR+可变电荷块——文献hub1
笔记·学习·知识图谱·学习方法
找了一圈尾巴4 小时前
Wend看源码-Java-Map学习
java·学习·map
山山而川粤7 小时前
母婴用品系统|Java|SSM|JSP|
java·开发语言·后端·学习·mysql
a49629868510 小时前
Xilinx FPGA的Bitstream比特流加密设置方法
fpga开发·代码保护·xilinx
一棵开花的树,枝芽无限靠近你11 小时前
【PPTist】表格功能
前端·笔记·学习·编辑器·ppt·pptist
LabVIEW开发12 小时前
LabVIEW条件配置对话框
fpga开发·labview数学
yuwinter12 小时前
鸿蒙HarmonyOS学习笔记(8)
笔记·学习
Ricciflows13 小时前
MIT线性代数教材:Linear Algebra and Its Applications
人工智能·学习·线性代数·机器学习·数学建模·矩阵