Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion filelist.f
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@
uvm/tb/apb_if.sv
uvm/tb/timer_if.sv
uvm/tb/apb_timer_uvm_pkg.sv
uvm/tb/apb_timer_tb_top.sv
uvm/tb/timer_sva.sv
uvm/tb/timer_cov.sv
uvm/tb/apb_timer_tb_top.sv
22 changes: 18 additions & 4 deletions uvm/tb/apb_timer_tb_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module apb_timer_tb_top;
logic pclk;
logic presetn;

// Clock generation
// Clock generation (100MHz / 10ns period)
initial begin
pclk = 0;
forever #5 pclk = ~pclk;
Expand All @@ -18,11 +18,24 @@ module apb_timer_tb_top;
end

// Interfaces
apb_if apb_vif (pclk, presetn);
apb_if apb_vif (pclk, presetn);
timer_if timer_vif (pclk, presetn);

// Connect TB TIMER loopback
// (No loopback needed for timer)
// Bind Functional Coverage module to DUT wrapper using internal wrapper signals
bind apb_timer_wrapper timer_cov u_timer_cov (
.clk (i_timer_pclk),
.rst_n (i_timer_presetn),
.timer_en (w_timer_en),
.oneshot_en (w_timer_oneshot),
.pwm_en (w_timer_pwm_en),
.prescaler (w_timer_prescaler),
.timer_val (w_timer_val),
.reload_val (w_timer_reload),
.compare_val (w_timer_compare),
.irq_en (u_apb_if.r_irq_en[1:0]),
.irq_stat (u_apb_if.r_irq_stat[1:0]),
.pwm_out (o_timer_pwm)
);

// DUT instantiation
apb_timer_wrapper #(
Expand All @@ -46,6 +59,7 @@ module apb_timer_tb_top;
.o_timer_irq (timer_vif.o_timer_irq)
);

// Pass virtual interfaces to UVM config DB & run test
// Bind SVA assertions module to DUT
bind apb_timer_wrapper timer_sva u_timer_sva (
.clk (i_timer_pclk),
Expand Down
110 changes: 110 additions & 0 deletions uvm/tb/timer_cov.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SystemVerilog Functional Coverage for APB Timer IP Core
`timescale 1ns/1ps

module timer_cov (
input logic clk,
input logic rst_n,
input logic timer_en,
input logic oneshot_en,
input logic pwm_en,
input logic [15:0] prescaler,
input logic [31:0] timer_val,
input logic [31:0] reload_val,
input logic [31:0] compare_val,
input logic [1:0] irq_en,
input logic [1:0] irq_stat,
input logic pwm_out
);

// ---------------------------------------------------------------------------
// 1. Control & Prescaler Coverage (Gated by rst_n)
// ---------------------------------------------------------------------------
covergroup cg_ctrl @(posedge clk iff rst_n);
option.per_instance = 1;

cp_timer_en: coverpoint timer_en;
cp_oneshot_en: coverpoint oneshot_en;
cp_pwm_en: coverpoint pwm_en;

cp_prescaler: coverpoint prescaler {
bins zero = {16'h0000};
bins one = {16'h0001};
bins max = {16'hFFFF};
bins mid_range = {[16'h0002 : 16'hFFFE]};
}

// Cross timer mode and prescaler classes
cross_mode_prescale: cross cp_oneshot_en, cp_prescaler;
endgroup

// ---------------------------------------------------------------------------
// 2. Reload, Compare, Counter & PWM Coverage (Gated by rst_n)
// ---------------------------------------------------------------------------
covergroup cg_timer_cfg @(posedge clk iff rst_n);
option.per_instance = 1;

cp_rel_cmp_rel: coverpoint (compare_val < reload_val) {
bins compare_less_than_reload = {1'b1};
bins compare_gte_reload = {1'b0};
}

cp_rel_cmp_equal: coverpoint (compare_val == reload_val) {
bins compare_equals_reload = {1'b1};
}

// Counter value coverage
cp_timer_val: coverpoint timer_val {
bins zero = {32'h0000_0000};
bins max_val = {32'hFFFF_FFFF};
bins mid_val = {[32'h0000_0001 : 32'hFFFF_FFFE]};
}

// PWM output activity & transitions
cp_pwm_out: coverpoint pwm_out {
bins low = {1'b0};
bins high = {1'b1};
bins low_to_high = (1'b0 => 1'b1);
bins high_to_low = (1'b1 => 1'b0);
}
endgroup

// ---------------------------------------------------------------------------
// 3. Interrupt Events, Masking & Write-1-to-Clear (Gated by rst_n)
// ---------------------------------------------------------------------------
covergroup cg_irq @(posedge clk iff rst_n);
option.per_instance = 1;

// Bit 0: Overflow IRQ, Bit 1: Compare Match IRQ
cp_irq_stat: coverpoint irq_stat {
bins none_asserted = {2'b00};
bins overflow_pending = {2'b01};
bins compare_pending = {2'b10};
bins both_pending = {2'b11};
}

cp_irq_en: coverpoint irq_en {
bins none_enabled = {2'b00};
bins overflow_enabled = {2'b01};
bins compare_enabled = {2'b10};
bins both_enabled = {2'b11};
}

// Write-1-to-Clear (W1C) transitions
cp_overflow_w1c: coverpoint irq_stat[0] {
bins overflow_cleared = (1'b1 => 1'b0);
}

cp_compare_w1c: coverpoint irq_stat[1] {
bins compare_cleared = (1'b1 => 1'b0);
}

// Cross status against both mask bits
cross_irq_mask: cross cp_irq_stat, cp_irq_en;
endgroup

// Instantiate covergroups
cg_ctrl cg_ctrl_inst = new();
cg_timer_cfg cg_timer_cfg_inst = new();
cg_irq cg_irq_inst = new();

endmodule
Loading