Thứ Ba, 26 tháng 11, 2019

[UVM] Bài 8 - Tạo báo cáo coverage và phân tích kết quả Coverage

Bài viết này trình bày về cách tạo báo cáo coverage (coverage report) và cách phân tích kết quả coverage trên một môi trường mô phỏng với phần mềm QuestaSim.


1) Coverage là gì?
Coverage, tạm dịch là mức độ bao phủ, là tỷ lệ phần trăm các mục tiêu kiểm tra đã được đáp ứng.
Ví dụ, mục tiêu kiểm tra của một thiết kế được xác định là 5 điểm. Mỗi mục tiêu kiểm tra sẽ ứng với một hoặc nhiều hoạt động, gọi là các chức năng (function), được thực hiện bởi một hoặc nhiều đoạn code. 5 mục tiêu được kỳ vọng sẽ giúp kiểm tra hết các chức năng và các đoạn code của thiết kế. Bạn sẽ cần tạo các testcase để kiểm tra 5 mục tiêu đã đặt ra. Để ước lượng kết quả kiểm tra, một số vấn đề sau cần được xác minh:
  • Làm thế nào để biết chắc rằng các chức năng và các đoạn code của thiết kế đã được kiểm tra toàn bộ hay chưa?
  • Làm thế nào để khẳng định số lượng testcase được tạo ra đã đáp ứng được 5 mục tiêu kiểm tra? Số lượng testcase đã đầy đủ hay chưa?
  • Làm thế nào để đánh giá tiến độ kiểm tra (verification progress) hiện tại?
*testcase là code dùng để thực thi kiểm tra thiết kế trên một môi trường mô phỏng. Mỗi testcase thường thực thi một trường hợp hoặc mục đích kiểm tra cụ thể.
Hình 1: Một thiết kế cần được kiểm tra (DUT) với 5 mục tiêu kiểm tra được xác định, mỗi mục tiêu sẽ kiểm tra một phần chức năng và code
Coverage là một thước đo hỗ trợ đánh giá các vấn đề trên. Ví dụ, coverage là 13/15, ứng với 86,667%, thể hiện:
  • Các chức năng và các đoạn code có thể chưa được kiểm tra toàn bộ. Các phần chưa được bao phủ cần được xem xét và đánh giá để xác định là cần được kiểm tra hay không.
  • Nếu các phần chưa được bao phủ cần phải kiểm tra, nghĩa là số lượng testcase đang bị thiếu và cần tạo thêm các testcase mới.
  • Việc lấy kết quả coverage theo từng giai đoạn có thể dùng làm thông số để ước lượng tiến độ kiểm tra.
Hình 2: Minh họa một kết quả coverage 13/15 = 86,667%
Việc dùng kết quả coverage để đánh giá tiến độ của quá trình kiểm tra thiết kế được thực hiện như sau:
  1. Xác định thời gian thực hiện kiểm tra, thời điểm bắt đầu và thời điểm kết thúc
  2. Xác định các mốc thời gian lấy kết quả coverage
  3. Thực thi các testcase trong từng giai đoạn và lấy kết quả coverage khi đến mốc thời gian đã xác định ở bước 2
Mốc thời gian
Tuần 1
Tuần 2
Tuần 3
Tuần 4
Tuần 5
Kết quả coverage
30%
40%
70%
95%
100%

Trong ví dụ trên, quá trình kiểm tra một thiết kế được xác định là 5 tuần, kết quả coverage sẽ được lấy vào cuối mỗi tuần. Thông qua kết quả coverage, tiến độ công việc kiểm tra thiết kế được thể hiện.
2) Phân loại coverage?
Covearge được chia làm hai nhóm chính là:
  • Code coverage là các thông tin coverage có thể được trích xuất tự động từ RTL code hoặc gate netlist, gọi chung là code, của thiết kế.
  • Function coverage là loại coverage được định nghĩa bởi người kiểm tra (user-defined) gắn liền với mục đích và chức năng thiết kế.
3) Code coverage
Code coverage là chức năng được hỗ trợ bởi hầu hết các phần mềm các phần mềm mô phỏng. Các phần mềm sẽ giúp trích xuất kết quả coverage từ RTL code hoặc gate netlist thông qua việc thực thi các testcase. Nguyên tắc cơ bản của code coverage là thống kê lại giá trị của các thành phần được mô tả trong code khi các testcase được thực thi.
Code coverage không được sử dụng để đánh giá:
  • Tính đầy đủ trong việc kiểm tra thiết kế. Một thiết kế có code coverage là 100% không có nghĩa là thiết kế này đã được kiểm tra toàn bộ các chức năng.
  • Tính đúng đắn của một thiết kế. Một thiết kế có code coverage 100% không có nghĩa là thiết kế này hoạt động chính xác 100%.
Code coverage không thể dùng để đánh giá 2 điểm trên vì việc thống kê được thực hiện độc lập trên các biến và các tín hiệu mà không xem xét đến chức năng và hoạt động của thiết kế. Nghĩa là không xem xét đến mối liên hệ của tất cả các thành phần trong thiết kế. Ví dụ, trong toggle coverage, ngõ vào của một khối trong thiết kế được báo là đạt 100%, điều này chỉ thể hiện là có sự chuyển trạng thái "từ 0 thành 1" và "từ 1 thành 0" trên tín hiệu, chứ không giúp khẳng định sự chuyển trạng thái này xảy ra đúng như chức năng mong muốn. 
Code coverage chỉ được dùng để đánh giá các điểm sau:
  • Hỗ trợ xác định các trường hợp test (testcase) bị thiếu. Khi coverage không đạt 100% thì phần code chưa được bao phủ có thể là phần code không được sử dụng (unused) hoặc phần code chưa được kiểm tra. Nếu là phần code chưa được kiểm tra, nghĩa là trường hợp test đang thiếu và cần tạo thêm testcase để kiểm tra phần code này.
  • Thống kê tác động của một testcase hoặc một nhóm testcase lên code cần kiểm tra. Ví dụ, sau khi chạy một testcase, thông qua báo cáo coverage, bạn có thể biết testcase này tác động lên những phần code nào của thiết kế.
Code coverage bao gồm các loại sau:
  • Statement coverage - mức độ bao phủ của các phát biểu, xác định xem một phát biểu (statement) trong code đã được thực thi hay chưa. Ví dụ về một phát biểu:
assign y = sel? a: b;
  • Branch coverage - mức độ bao phủ của các nhánh, dùng để đánh giá sự thực thi của cấu trúc rẽ nhánh if/elsecase. Một cấu trúc rẽ nhánh chỉ được bao phủ 100% khi tất cả các nhánh đều đã được thực thi. Ví dụ, cấu trúc if/else sau đây được bao phủ 100% nếu cả 3 nhánh if, else if else đều đã được thực thi.
if (a == 1)
  y = 0;
else if (b = 1)
  y = 2;
else
  y = 1;
  • Condition coverage - mức độ bao phủ của các điều kiện, dùng để đánh giá và phân tích các điều kiện mô tả trong các nhánh của phát biểu if và toán tử điều kiện ?. Tùy và phần mềm, nó có thể là một phần của branch coverage hoặc là một báo cáo riêng. Một điều kiện chỉ được bao phủ 100% khi tất cả các giá trị làm cho điều kiện đó đúng (TRUE) và sai (FALSE) đều xuất hiện. Ví dụ, điều kiện state == IDLE sau đây chỉ được bao phủ 100% nếu state bằng IDLE và state khác IDLE đã xảy ra.
if (state == IDLE)
  • Expression coverage - mức độ bao phủ của các biểu thức, dùng để đánh giá biểu thức bên vế phải của một phép gán. Một biểu thức được bao phủ 100% khi tất cả tổ hợp giá trị của các biến trong biểu thức đã xuất hiện. Ví dụ, biểu thức sau chỉ được xem là bao phủ 100% nếu tất cả các tổ hợp giá trị của {a, b}00, 01, 1011 đều đã xuất hiện.
assign y = a & b;
  • Toggle coverage - mức độ bao phủ của sự thay đổi trạng thái, dùng để đánh giá sự thay đổi trạng thái trên các tín hiệu. Một tín hiệu chỉ được bao phủ 100% khi nó đã xuất hiện sự chuyển mức logic từ 0 thành 1 và ngược lại. Đối với tín hiệu 3 trạng thái (tri-state) thì có thể cần phải thêm sự chuyển đổi từ 0 1 thành Z và từ Z thành 0 1.
Ngoài ra một số phần mềm còn hỗ trợ các loại coverage khác như:
  • FSM coverage - mức độ bao phủ của FSM, dùng để đánh giá riêng máy trạng thái
  • Class Coverage -  mức độ bao phủ của class, dùng để đánh giá riêng các class của System Verilog
Hình 3: Phân loại coverage
4) Function coverage
Fucntion coverage thuộc về người dùng định nghĩa chứ không thể được trích xuất tự động bằng phần mềm. Người kiểm tra sẽ phải mô tả cụ thể điểm cần được bao phủ bằng System Verilog. Dựa trên mô tả này, phần mềm sẽ giám sát và báo cáo kết quả coverage.  Các điểm quan trọng của function coverage là:
  • Người kiểm tra phải định nghĩa điểm cần bao phủ
  • Điểm cần bao phủ được định nghĩa dựa trên tài liệu mô tả kỹ thuật (specification) và đặc điểm mong muốn của thiết kế chứ không phụ thuộc vào cấu trúc hoặc code của thiết kế
  • Function coverage có thể hỗ trợ đánh giá tính đầy đủ và đúng đúng đắn của thiết kế. Điều mà code coverage không hỗ trợ được.
Function coverage có thể được dùng để giám sát và xác nhận các điểm sau:
  • Một đặc điểm hoặc chức năng nào đó của thiết kế hoạt động đúng. Ví dụ, một biến trong thiết kế phải thay đổi giá trị tuần tự 1 -> 3 -> 5 -> 8. Code coverage chỉ cho biết biến này đã xuất hiện những giá trị nào chứ không cho biết các giá trị đã xuất hiện có theo đúng thứ tự như yêu cầu thiết kế hay không. Function coverage sẽ giúp giám sát điều này.
  • Một điều kiện hoặc trường hợp kiểm tra đã xảy ra hay chưa. Trong một số trường hợp, điều kiện kiểm tra tạo ra từ testcase cần được xác nhận để đảm bảo rằng testcase thực thi đúng trường hợp như mong muốn.
SV có hỗ trợ các thành phần như covergroup, coverpoint, cross, các tùy chọn, task và function giúp người kiểm tra có thể mô tả function coverage.
5) Mô tả fucntion coverage với SV
Phần  này không nhằm mục đích trình bày chi tiết cách thức mô tả function coverage với SV mà chỉ thực hiện một ví dụ nhỏ về function coverage giúp bạn đọc hiểu rõ hơn function coverage là gì?
Trong môi trường mô phỏng đã xây dựng, một ví dụ về function coverage được thêm vào file ./checker/uart_protocol_checker.sv để kiểm tra trường hợp truyền back-to-back của giao thức UART. Back-to-back là truyền liên tiếp các gói dữ liệu UART mà không có khoảng thời gian rảnh giữa các gói. Nghĩa là bit START của gói sau nối tiếp ngay sau bit STOP của gói trước.
Hình 4: Truyền back-to-back của giao thức UART
Để đảm bảo chức năng này xảy ra, một điểm bao phủ sẽ được mô tả để kiểm tra frame_start và frame_end cùng tích cùng mức 1 trong khhi checker đang ở trạng thái CHK_UART_CHECK. Ở đây,
  • frame_end báo kết thúc một khung UART, ngay sau bit STOP
  • frame_start phát hiện một cạnh xuống của bit START
  • checker đang ở trạng thái CHK_UART_CHECK là để đảm bảo nó đang trong một trạng thái kiểm tra khung UART
Hình 5: Vị trí đặt điểm bao phủ (coverpoint) để đảm bảo có sự truyền nhận back-to-back trên giao thức UART
Ví dụ 1 - SV code mô tả một function coverage
 covergroup back_2_back @ (posedge pclk);
    coverpoint chk_uart_state {
      bins pass[] = {1} iff (frame_start && frame_end) ;
    }
    option.per_instance = 1;
  endgroup
  back_2_back b2b = new();
  initial begin
    b2b.sample();
  end
Trong đoạn code trên:
  • Tên covergroup back_2_back, việc lấy mẫu kiểm tra giá trị cần bao phủ được thực hiện tại cạnh lên pclk
  • Tín hiệu cần kiểm tra là chk_uart_state phải bằng 1, pass[] = {1}, trong khi frame_start=1 frame_end=1iff (frame_start && frame_end)
  • option.per_instance = 1 để cho phép thông tin của một instance tạo từ covergroup này được thống kê trong dữ liệu coverage và báo cáo coverage.
  • Tạo một instance covergroup bằng new()
  • sample() là một hàm hỗ trợ bở SV dùng để kích hoạt việc lấy mẫu covergae
6) Cách tạo báo cáo coverage với QuestaSim
Phần mềm được sử dụng là QuestaSim 10.2c. Việc tạo một báo cáo coverage trên phần mềm này được thực hiện như sau:
  • Lệnh vlog: Tổng hợp source code với tùy chọn "+cover". Tùy chọn này cho phép thu thập các kết quả coverage khác nhau trên tất cả các thành phần trong thiết kế. Tùy chọn này đi kèm với các giá trị sau:
    • b - cho phép branch coverage
    • c - cho phép condition coverage, chỉ thu thập loại ocverage FEC (Focused Expression Coverage)
    • e - cho phép expression coverage, chỉ thu thập loại ocverage FEC
    • s - cho phép statement coverage
    • t - cho phép toggle coverage, tùy chọn này có thể bị ghi đè bởi tùy chọn "x"
    • x - cho phép toggle coverage mở rộng, thêm việc giám sát chuyển trạng thái từ 0,1 thành Z và ngược lại.
    • f - cho phép FSM coverage
Ví dụ 2 - Lệnh tổng hợp source code cho phép coverage (chú ý dòng bôi đỏ, đây là đường dẫn thư viện UVM)
my $vlog = "$VLog -work work \\
+define+UVM_CMDLINE_NO_DPI \\
+define+UVM_REGEX_NO_DPI \\
+define+UVM_NO_DPI \\
+define+INTERRUPT_COM \\
+incdir+C:/questasim64_10.2c/uvm-1.2/src \\
-sv \\
../dut/uart_apb_if.v \\
../dut/uart_receiver.v \\
../dut/uart_transmitter.v \\
../dut/uart_top.v \\
../dut/dut_top.v \\
../checker/apb_protocol_checker.sv \\
../checker/apb_protocol_checker_top.sv \\
../checker/uart_protocol_checker.sv \\
../checker/uart_protocol_checker_top.sv \\
../uvm_comp/ifDut.sv \\
testTop.sv \\
-timescale 1ns/1ns \\
-l vlog.log \\
+cover=bcestf \\
    -coveropt 1
";
  • Lệnh vsim - Chạy mô phỏng và tạo cở sở dữ liệu coverage (coverage database). Cơ sở dữ liệu coverage được lưu trong file .ucdb. UCDB là viết tắt của Unified Coverage Database. với các tùy chọn
    • -coverage : cho phép thu thập các thống kê của code coverage trong quá trình chạy mô phỏng
    • -coveranalysis : lưu các điểm toggle vào file UCDB
    • -cvgperinstance :  thiết lập giá trị của  option.per_instance của tất cả các covergroup bằng 1.
    • -do : dùng tùy chọn này để thực thi một lệnh lưu cơ sở dữ liệu coverage.
  • Lệnh lưu cơ sở dữ liệu trong tùy chọn "-do" của vsim "coverage save -codeAll -cvg -onexit $ARGV[0].ucdb". Ý nghĩa của lệnh này như sau:
    • coverage save : lệnh lưu kết quả coverage với các loại coverage được mô tả trong một file .ucdb
    • -codeAll : Tất cả các loại coverage, tương được với tùy chọn " -code bcestf " 
    • -cvg : lưu lại dữ liệu của covergroup, cái dùng để đặc tả function coverage
    • -onexit : tự động lưu lại dữ liệu coverage khi thoát trình mô phỏng
    • $ARGV[0].ucdb : tên file cơ sở dữ liệu coverage. Trong script này, tên file là <tên testcase>.ucdb
Ví dụ 3 - Lệnh chạy mô phỏng và tạo cơ sở dữ liệu coverage
my $vsim = "$VSim -c -novopt work.testTop \\
+UVM_TESTNAME=cTest \\
+UVM_VERBOSITY=UVM_LOW \\
-do \"coverage save -codeAll -cvg -onexit $ARGV[0].ucdb; run -all;\" \\
-coverage \\
    -coveranalysis \\
-cvgperinstance \\

-l vsim.log";
  • Tạo báo cáo coverage cho một testcase
    • vcover report : Lệnh tạo báo cáo coverage
    • -html : tùy chọn tạo file báo cáo dạng HTML. File này được mở dễ dàng bằng các trình duyệt web như chrome, firefox, ...
    • -htmldir : chỉ định thư mục lưu báo cáo coverage
    • -code : chọn các loại code coverage sẽ có trong báo cáo
    • -cvg : hiển thị coverage group trong báo cáo
    • $ARGV[0].ucdb : tên file cơ sở dữ liệu coverage được tạo ra ở bước chạy mô phỏng phía trên
Ví dụ 4 - Lệnh tạo báo cáo coverage cho một testcase
my $vcover = "$VCov report -html -code bcestf -testhitdata -cvg $ARGV[0].ucdb";
  • Tạo báo cáo coverage cho toàn bộ kết quả chạy mô phỏng gồm nhiều testcase (merge coverage)
    • Lưu cơ sở dữ liệu coverage của mỗi testcase đến thư mục ./cov sau mỗi lần chạy mô phỏng bằng cách sao chép file cở dữ liệu sau khi chạy một testcase đến thư mục ./cov.
Ví dụ 5 - Lưu lại cơ sở dữ liệu coverage của mỗi testcase
system "cp -rf $ARGV[0].ucdb ../cov/";
    • Thực thi hợp nhất (merge) các cơ sở dữ liệu coverage. Lệnh sau đây sẽ hợp nhất tất cả các cơ sở dữ liệu của từng testcase lưu trong ./cov thành một file cơ sở dữ liệu tên mergedCov.ucdb
Ví dụ 6 - Lệnh hợp nhất các cơ sở dữ liệu
my $vmerge = "$VCov merge mergedCov.ucdb ../cov/*.ucdb";
  • Tạo file báo cáo coverage từ cơ sở dữ liệu đã được hợp nhất. Lệnh sau đây sẽ tạo file báo cáo tên index.html (tên mặc định) trong thư mục ./sim từ cơ sở dữ liệu đã hợp nhất trong file mergedCov.ucdcb.
Ví dụ 7 - Tạo file báo cáo
my $vcover = "$VCov report -html -htmldir ./ -code bcestf -cvg mergedCov.ucdb";
Chi tiết được thể hiện trong một script Perl tên ./sim/run_qsim.pl có thể tải cuối bài viết. Với môi trường này, các bạn chạy từng testcase bằng lệnh:
./run_qsim.pl <tên testcase>
Sau khi chạy toàn bộ hoặc một vài testcase, báo cáo coverage tổng hợp có thể được tạo bằng lệnh
./run_qsim.pl MERGE_COVERAGE
Mở file ./sim/index.html để kiểm tra kết quả coverage. Một số điểm quan trọng cần lưu ý:
  1. run_qsim.pl là Perl script sử dụng các biến đại diện cho các lệnh của QuestaSim như sau:
    • $VLog ứng với vlog
    • $VSim ứng với vsim
    • $VCov ứng với vcover
  2. Script chạy với Cygwin terminal trên hệ điều hành Windows
  3. Các tùy chọn của từng lệnh đã giới thiệu trên đây có thể khác nhau trên các phiên bản phần mềm khác nhau. Vì vậy, bạn cần kiểm tra lại các lệnh và các tùy chọn với tài liệu tên "Command Reference Manual" kèm theo phần mềm đang sử dụng.
  4. Báo cáo coverage với định dạng .html có thể chỉ được mở trên một số trình duyệt web và phiên bản trình duyệt nhất định
  5. Định dạng của báo cáo coverage có thể khác nhau trên các phiên bản phần mềm khác nhau.
  6. Phần mềm không có license thương mại sẽ bị hạn chế một số chức năng coverage, ví dụ như báo cáo coverage không được tạo ra chi tiết và đầy đủ.
7) Phân tích kết quả coverage
7.1) Báo cáo tổng quan
Tác giả chạy lệnh sau đây để lấy kết quả coverage cho testcase tên trialPat.
./run_qsim.pl trialPat
Sau khi chạy, dùng một trình duyệt web như Firefox, Chrome, ... để mở file ./sim/index.html, các bạn sẽ quan sát thấy như sau:
Hình 6: Báo cáo coverage
Kết quả coverage của từng thành phần trong môi trường được thể hiện bằng chỉ số % mức độ bao phủ. Mỗi loại coverage được sắp xếp thành từng cột, ứng với các tùy chọn đã trình bày ở mục trên.
  • Phần bên trái ngoài cùng liệt kê tất cả các thành phần được lấy coverage theo cấu trúc môi trường mô phỏng
  • Phần bên phải là báo cáo tổng hợp từng loại coverage
Bên dưới báo cáo tổng hợp này sẽ có báo cáo chi tiết. Báo cáo chi tiết này sẽ liên kết đến các báo cáo phân tích giúp người kiểm tra xác định các thành phần code hoặc chức năng (function) chưa được kiểm tra. Báo cáo chi tiết gồm các cột sau:

  • Coverage Type: Liệt kê loại coverage
  • Bins: Tổng số điểm kiểm tra được thống kế
  • Hits: Số điểm đã được bao phủ 100%
  • Misses: Số điểm chưa được bao phủ. Các điểm này có thể được bao phủ một phần hoặc hoàn toàn chưa được bao phủ.
  • Weight: Trọng số bao phủ, mặc định là 1
  • %Hit: là tỷ số của Hits/Bins
  • Coverage: là kết quả coverage

Hình 7: Báo cáo chi tiết xuất hiện bên dưới báo cáo tổng hợp
Đây cũng là cấu trúc chung của một một báo cáo coverage trên QuestaSim, nó gồm:
  • Một báo cáo tổng hợp bên trên giúp đánh giá nhanh kết quả
  • Một báo cáo chi tiết bên dưới giúp liên kết đến các báo cáo phân tích kết quả
Người kiểm tra có thể truy xuất kết quả coverage của các thành phần nằm sâu hơn trong cấu trúc môi trường, các sub-instance, bằng các click vào các liên kết trên báo cáo coverage. Sau đây, tác giả sẽ phân tích cụ thể báo cáo của từng loại coverage.
Hình 8: Báo cáo coverage của intance uart0_chk trong testTop.uart_protocol_checker_top
7.2) Function coverage
Như đã trình bày ở trên function coverage là do người kiểm tra dịnh nghĩa bằng SV. Phần mềm sẽ thống kê lại các instance của covergroup mà người dùng định nghĩa.
Trong ví dụ này, chúng ta sẽ xem kết quả của của instance b2b, được tạo từ covergroup back_2_back, trong testTop.uart_protocol_checker_top.uart0_chk.
Hình 9: Báo cáo coverage của covergroup trong function coverage
Báo cáo trên có 3 bảng thể hiện 3 thông tin:
  • Bảng 1 thống kê số instance của các covergroup
  • Bảng 2 thống kê số coverpoint của các covergroup
  • Bảng 3 thống kê số bins của các coverpoint
7.3) Statements coverage
Báo cáo cho các loại code coverage sẽ được minh họa trên instance testTop.dut_top.uart_0.transmitter.
Hình 10: Báo cáo coverage của instance testTop.dut_top.uart_0.transmitter
Click vào các loại coverage tương ứng trong cột "Coverage Type" sẽ xem được báo cáo chi tiết của từng loại. Để xem báo cáo chi tiết của kết quả coverage, click vào Statements.
Hình 11: Báo cáo statement coverage
Trong báo cáo chi tiết của Statements coverage:
  • Các dòng code màu đen không thuộc phạm vi thống kê của statement coverage. Chúng sẽ được thống kê trong các loại báo cáo coverage khác.
  • Các dòng code được tô xanh là các phát biểu đã được thực thi, ứng với đã bao phủ.
  • Các dòng code được tô đỏ là các trường hợp code chưa được thực thi, ứng với chưa bao phủ. Các điểm chưa bao phủ cần được xem xét để thêm testcase kiểm tra hoặc bỏ qua dựa trên mô tả của thiết kế.
Hình 12: Báo cáo thể hiện chi tiết các dòng code đã được bao phủ và chưa được bao phủ
Trong báo cáo trên, ở phát biểu case(ctrl_txt[1:0]), code chỉ mới thực thi trường hợp đầu tiên, ứng với ctrl_txt=2'b00, ba trường hợp còn lại và nhánh default chưa được thực thi. Như vậy, người kiểm tra phải tạo thêm testcase để kiểm tra trường hợp 2'b01, 2'b102'b11. Nhánh default không cần phải bao phủ vì ctrl_txt[1:0] chỉ có 2 bit nên chỉ cần bao phủ đủ 4 trường hợp.
7.4) Branches coverage
Báo cáo thể hiện rõ nhánh điều kiện nào đã bao phủ, ứng với Status Covered và nhánh nào chưa bao phủ, ứng với Status là ZERO.
Nếu đã bao phủ, cột Hits sẽ cho biết số lần nhánh này được thực thi trong testcase hiện tại. Nếu chưa bao phủ, cột Hits sẽ là 0.
Hình 13: Báo cáo branch coverage
Cột Branch sẽ cho biết nhánh nào của điều kiện chưa được thực thi. Người kiểm tra có thể click vào tiêu đề của bảng báo cáo để xem RTL code tương ứng.
Hình 14: Dòng 68 là RTL code của bảng cáo cáo 3
7.5) Expressions coverage
Expressions coverage của QuestaSim dùng cơ chế FEC (Focused Expression Coverage) để đánh giá kết quả coverage.
FEC là một cơ chế đánh giá kết quả coverage trên các ngõ vào của một biểu thức. Biểu thức là vế phải của một phép gán hoặc một biểu thức điều kiện. Nguyên tắc của FEC là một biểu thức gọi là được bao phủ 100% nếu tất cả các ngõ vào của nó được bao phủ đầy đủ. Một ngõ vào được bao phủ đầy đủ bằng cách áp dụng phương pháp sau đây:
  • Tất cả các ngõ vào khác phải trong trạng thái cho phép ngõ vào này điều khiển giá trị ngõ ra
  • Ngõ ra phải đạt cả hai giá trị 0 1 khi ngõ vào này điều khiển
Giá trị coverage được tính bằng số ngõ vào được bao phủ đầy đủ chia tổng số ngõ vào.
Hình 15: Báo cáo expression coverage theo cơ chế FEC
Với mỗi biểu thức, kết quả sẽ gồm 2 bảng. Ví dụ trên đây là báo cáo cho biểu thức:
tx_shift_complete = ctrl_d9? (shift_tx_counter[3:0]==4'd10): (shift_tx_counter[3:0]==4'd9)
  • Bảng đầu tiên: báo cáo trên từng ngõ vào của biểu thức, trường hợp này là 3 ngõ vào là ctrl_d9, shift_tx_counter[3:0]==10shift_tx_counter[3:0]==9. Báo cáo gồm các cột sau:
    • Covered: Ngõ vào đã được bao phủ hay chưa
      • No: Chưa bao phủ
      • Yes: Đã bao phủ
    • Reason For No Coverage: Lý do của trường hợp chưa bao phủ (No). Trong ví dụ này, lý do gồm:
      • ctrl_d9 đã xảy ra trường hợp bằng 0 ('_0' hit) nhưng chưa xảy ra trường hợp bằng 1 (but '_1' not hit)
      • shift_tx_counter[3:0]==10 chưa xảy ra trường hợp nào (No hits) tác động đến kết quả ngõ ra  tx_shift_complete. Chú ý, "No hits" nghĩa là ngõ vào này chưa được tác động để điều khiển ngõ ra chứ không phải có ý nghĩa "chưa xảy ra trường hợp bộ đếm bằng 10". Bạn hãy xem lại giải thích về FEC. Ở đây, vì ctrl_d9 chưa bằng 1 nên nhánh này chưa được chọn, vì vậy, chưa được bao phủ.
    • Hint hướng dẫn làm thế nào để bao phủ trường hợp này. Trong ví dụ này, để bao phủ các trường hợp No, chúng ta cần thực hiện:
      • Đối với ngõ vào ctrl_d9: Lái ctrl_d9=1 (Hit '_1') và làm cho ngõ ra xuất hiện giá trị 0 hoặc 1 (for output ->0 or ->1)
      • Đối với shift_tx_counter[3:0]==10: Biểu thức này phải được lái giá trị ngõ ra bằng 0 và 1.

*Ghi chú: '_0 và '_1' ứng với phần hậu tố (suffix) được thêm vào các ngõ vào ở bảng chi tiết thứ 2.
  • Bảng thứ 2 sẽ chi tiết hóa từng trường hợp bao phủ của ngõ vào.
    • FEC Target là tên tín hiệu với hậu tố thể hiện giá trị cần được bao phủ. Ví dụ, ctrl_d9_0 là trường hợp ctrl_d9=0.
    • Hits (->0) là trường hợp bao phủ mà ngõ vào lái ngõ ra biểu thức bằng 0. Nếu giá trị cột này là 1 thì trường hợp này đã xảy ra, bằng 0 là chưa xảy ra. Ví dụ, cột này của ctrl_d9_0=1 chứng tỏ đã xảy ra trường hợp ctrl_d9=0 và làm ngõ ra tx_shift_complete=0
    • Hits (->1) là trường hợp bao phủ mà ngõ vào lái ngõ ra biểu thức bằng 1. Nếu giá trị cột này là 1 thì trường hợp này đã xảy ra, bằng 0 là chưa xảy ra. Ví dụ, cột này của ctrl_d9_0=1 chứng tỏ đã xảy ra trường hợp ctrl_d9=0 và làm ngõ ra tx_shift_complete=1
    • Matching Input Patterns (->0) thể hiện giá trị của 3 ngõ vào theo thứ tự đã làm cho ngõ ra bằng 0. Ví dụ, cột này của ctrl_d9_0 là {0-0} chứng tỏ trường hợp sau đã xuất hiện làm ngõ ra bằng 0:
      • ctrl_d9=0
      • shift_tx_counter[3:0]==10 không được thống kê giá trị trong trường hợp này, ứng với dấu "-"
      • shift_tx_counter[3:0]==9 bằng 0, ứng với shift_tx_counter khác 9
    • Matching Input Patterns (->1) thể hiện giá trị của 3 ngõ vào theo thứ tự đã làm cho ngõ ra bằng 1. Ví dụ, cột này của ctrl_d9_0 là {0-1} chứng tỏ trường hợp sau đã xuất hiện làm ngõ ra bằng 1:
      • ctrl_d9=0
      • shift_tx_counter[3:0]==10 không được thống kê giá trị trong trường hợp này, ứng với dấu "-"
      • shift_tx_counter[3:0]==9 bằng 1, ứng với shift_tx_counter đã bằng 9
Trong bảng trên, ký hiệu "E-Miss" và "Not Testable" thể hiện một trường hợp không thể kiểm tra. Ví dụ, trường hợp (shift_tx_counter[3:0]==9)_0, đây là trường hợp ngõ vào phải bằng 0, tức shift_tx_counter[3:0] khác 9. Trong biểu thức này, khi ctrl_d9=0 mà shift_tx_counter[3:0] khác 9 thì chỉ có thể làm ngõ ra bằng 0, không bao giờ "shift_tx_counter[3:0] khác 9" mà làm ngõ ra bằng 1. Vì vậy, cột Hits (->1) là "E-Miss" và cột Matching Input Patterns (->1) là "Not Testable".
Chú ý, bạn có thể click vào biểu thức ở đầu bảng báo cáo để xem file code chứa biểu thức này.
7.6) Conditions coverage
Báo cáo của condition coverage gần tương tự như expression coverage.Báo cáo này cũng theo cơ chế thống kế FEC. Bạn đọc có thể tự phân tích chi tiết. Mỗi điều kiện sẽ được thống kê kết quả bằng 2 bảng. Ở hình minh họa dưới đây, điều kiện sau đây được thể hiện:
else if ((state == IDLE) & load_data)
Điều kiện này không được bao phủ trường hợp (state==IDLE) bằng 0, ứng với state khác IDLE.
Hình 16: Báo cáo condition coverage
Trong báo cáo condition coverage và expression coverage, cột "Matching ..." thay bằng cột "Non-Masking Conditions(s)" trong các phiên bản mới hơn của QuestaSim. Cột này chỉ cung cấp tổ hợp giá trị của các ngõ vào còn lại trong biểu thức giúp ngõ vào cần bao phủ có thể lái được ngõ ra.
Hình 17: Báo cáo condition coverage của phiên bản QuestaSim mới hơn bản 10.2c
Xét lại điều kiện ((state == IDLE) & load_data), quan sát cột Non-Masking Condition(s) ứng với Row 1, giá trị cột này là load_data, điều này nghĩa là load_data phải bằng 1 thì biểu thức state == 0 (0 là IDLE) mới có thể ảnh hưởng (quyết định) đến giá trị ngõ ra.
7.7) Toggles coverage
Kết quả của báo cáo này được tính bằng công thức:
Mức độ bao phủ (Status) = số hit / tổng số trường hợp chuyển trạng thái được kiểm tra 
Trong ví dụ này, toggle coverage chỉ kiểm tra 2 trường hợp:
  • Chuyển từ 0 sang 1
  • Chuyển từ 1 sang 0
Không kiểm tra các trường hợp:
Chuyển từ 0 sang Z
Chuyển từ 1 sang Z
Chuyển từ Z sang 0
Chuyển từ Z sang 1
Muốn kiểm tra toàn bộ trường hợp, trong các lệnh tổng hợp và chạy mô phỏng. Bạn cần chọn "x" thay vì "t". Ví dụ, lệnh vlog sẽ dùng tùy chọn sau:
+cover=bcesfx
thay cho tùy chọn:
+cover=bcestf
Hình 18: Báo cáo condition coverage
Bài viết đã giới thiệu cơ bản về coverage và phân tích các báo cáo coverage với phần mềm QuestaSim 10.2c. Bạn có thể tải môi trường đầy đủ về để kiểm tra thử.

Dữ liệu có thể tải: 

Lịch sử cập nhật:
1/ 2019.11.26 - Tạo lần đầu

Danh sách tác giả:
1. Phạm Thanh Trâm
2. Đoàn Đức Hoàng
3. Trương Công Hoàng Việt
4. Nguyễn Sinh Tơn
5. Nguyễn Hùng Quân

2 bình luận:

  1. Function coverage được mô tả bao nhiêu là đủ đối với một thiết kế cần được kiểm tra?

    Trả lờiXóa
    Trả lời
    1. Hi, số lượng function coverage được mô tả dựa trên những đặc điểm và chức năng mà người thiết kế cần cover.
      Trên thực tế việc mô tả function coverage một cách đầy đủ sẽ tốn nhiều thời gian nên hiện nay, nó được dùng chủ yếu để cover một số điểm kiểm tra thực sự quan trọng hoặc corner case. Lúc này, người kiểm tra tập trung vào 2 việc, tạo số lượng testcase đủ để kiểm tra các chức năng và đảm bảo code coverage là 100%

      Xóa