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
2 changes: 1 addition & 1 deletion hw/ip/adc_ctrl/dv/env/adc_ctrl_env.core
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ filesets:
- seq_lib/adc_ctrl_base_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_common_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_smoke_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_random_ramp_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_channel_ramp_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_filters_polled_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_filters_interrupt_vseq.sv: {is_include_file: true}
- seq_lib/adc_ctrl_filters_wakeup_vseq.sv: {is_include_file: true}
Expand Down
83 changes: 83 additions & 0 deletions hw/ip/adc_ctrl/dv/env/seq_lib/adc_ctrl_channel_ramp_vseq.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// A ramp virtual sequence that controls an ADC channel, ramping between two values. This is a
// virtual sequence because it works entirely by controlling an existing push_pull sequence through
// a config object.

class adc_ctrl_channel_ramp_vseq extends uvm_sequence;
// A config object for the push/pull agent through which we will control the ADC channel
adc_push_pull_config_t push_pull_cfg;
// An event that the environment will trigger when a push/pull item is received on this channel.
event push_pull_ev;

// Start value of the ramp
rand adc_value_t ramp_start;
// End value of the ramp
rand adc_value_t ramp_end;
// Minimum ramp step
rand int unsigned ramp_step_min;
// Maximum ramp step
rand int unsigned ramp_step_max;

// Constrain the ramp start and end values to be less than (1 << ADC_CTRL_DATA_WIDTH). Constrain
// the range of step sizes (ensuring that they are bounded above by ramp_step_max, which means
// we're unlikely to jump the whole way in one go).
extern constraint ramp_constraints_c;

extern function new(string name="");
extern task body();
extern task send_adc_data(adc_value_t value);

`uvm_object_utils_begin(adc_ctrl_channel_ramp_vseq)
`uvm_field_int(ramp_start, UVM_DEFAULT | UVM_DEC)
`uvm_field_int(ramp_end, UVM_DEFAULT | UVM_DEC)
`uvm_field_int(ramp_step_min, UVM_DEFAULT | UVM_DEC)
`uvm_field_int(ramp_step_max, UVM_DEFAULT | UVM_DEC)
`uvm_object_utils_end
endclass

constraint adc_ctrl_channel_ramp_vseq::ramp_constraints_c {
ramp_start < (1 << ADC_CTRL_DATA_WIDTH);
ramp_end < (1 << ADC_CTRL_DATA_WIDTH);

1 <= ramp_step_max;
ramp_step_min <= ramp_step_max;
}

function adc_ctrl_channel_ramp_vseq::new(string name="");
super.new(name);
endfunction

task adc_ctrl_channel_ramp_vseq::body();
// Current value for the channel (starts at the starting value)
adc_value_t current_value = ramp_start;

// Send the starting value through the push/pull agent
send_adc_data(current_value);

// Increment/decrement the ADC channel data until we get to the end value
while (current_value != ramp_end) begin
// Pick a random ramp step size in [ramp_step_min:ramp_step_max].
int unsigned ramp_step = $urandom_range(ramp_step_min, ramp_step_max);

// Update the current value of the ramp accordingly, clamping to ramp_end
if (current_value < ramp_end) begin
current_value += min2(ramp_step, ramp_end - current_value);
end else begin
current_value -= min2(ramp_step, current_value - ramp_end);
end

// Send next data via ADC bus
send_adc_data(current_value);
end
endtask

task adc_ctrl_channel_ramp_vseq::send_adc_data(adc_value_t value);
push_pull_cfg.clear_d_user_data();
push_pull_cfg.add_d_user_data(value);

// Wait to be told that data was received (via the scoreboard)
@push_pull_ev;
endtask
170 changes: 90 additions & 80 deletions hw/ip/adc_ctrl/dv/env/seq_lib/adc_ctrl_filters_polled_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ class adc_ctrl_filters_polled_vseq extends adc_ctrl_base_vseq;

constraint num_trans_c {num_trans inside {[1 : 3]};}

`uvm_object_new
function new (string name="");
super.new(name);
endfunction

virtual task pre_start();
super.pre_start();
Expand All @@ -25,86 +27,95 @@ class adc_ctrl_filters_polled_vseq extends adc_ctrl_base_vseq;
disable check_adc_ctrl_status;
endtask

virtual task body();
uvm_reg_data_t rdata;
adc_ctrl_random_ramp_vseq random_ramp_vseq;

repeat (num_trans) begin

// Make sure ADC is off
csr_wr(ral.adc_en_ctl, 'h0);

// Set up the adc_ctrl registers
configure_adc_ctrl();

// Clear interrupt status reg
csr_wr(ral.adc_intr_status, '1);

// Check interrupt status is cleared
csr_rd_check(.ptr(ral.adc_intr_status), .compare_value(0),
.err_msg(called_from(`__FILE__, `__LINE__)));

// Start ADC
ral.adc_en_ctl.adc_enable.set(1);
case (cfg.testmode)
AdcCtrlTestmodeOneShot: begin
ral.adc_en_ctl.oneshot_mode.set(1);
ral.adc_pd_ctl.lp_mode.set(0);
end
AdcCtrlTestmodeNormal: begin
ral.adc_en_ctl.oneshot_mode.set(0);
ral.adc_pd_ctl.lp_mode.set(0);
end
AdcCtrlTestmodeLowpower: begin
ral.adc_en_ctl.oneshot_mode.set(0);
ral.adc_pd_ctl.lp_mode.set(1);
end
default: `uvm_fatal(`gfn, "Undefined test mode")
endcase
csr_wr(ral.adc_pd_ctl, ral.adc_pd_ctl.get());
csr_wr(ral.adc_en_ctl, ral.adc_en_ctl.get());

// Hook to do things immediately after the adc_ctrl is enabled
post_adc_ctrl_enable();

// Send randomized ramp on all channels - rising
`uvm_create_obj(adc_ctrl_random_ramp_vseq, random_ramp_vseq)
random_ramp_vseq.set_sequencer(p_sequencer);
// verilog_format: off - avoid bad formatting
`DV_CHECK_RANDOMIZE_WITH_FATAL(random_ramp_vseq,
ramp_min == 0;
ramp_max == adc_value_t'('1);
ramp_step_min == 0;
ramp_step_max == 5;
ramp_rising == 1;)
// verilog_format: on
random_ramp_vseq.start(p_sequencer, this);
`uvm_info(`gfn, random_ramp_vseq.sprint(uvm_default_line_printer), UVM_MEDIUM)

// Send randomized ramp on all channels - falling
`uvm_create_obj(adc_ctrl_random_ramp_vseq, random_ramp_vseq)
random_ramp_vseq.set_sequencer(p_sequencer);
// verilog_format: off - avoid bad formatting
`DV_CHECK_RANDOMIZE_WITH_FATAL(random_ramp_vseq,
ramp_min == 0;
ramp_max == adc_value_t'('1);
ramp_step_min == 0;
ramp_step_max == 5;
ramp_rising == 0;)
// verilog_format: on
random_ramp_vseq.start(p_sequencer, this);
`uvm_info(`gfn, random_ramp_vseq.sprint(uvm_default_line_printer), UVM_MEDIUM)
// Now turn off ADC_CTRL
adc_ctrl_off();

// FSM reset to synchronise RTL & model
do_adc_fsm_reset();

// Re-randomize configuration if enabled
if (!cfg.filters_fixed) `DV_CHECK_RANDOMIZE_FATAL(cfg)
// Run a randomised vseq to ramp channel from start_value to end_value
//
// The increments each time will be randomised in the range [0, 20], so we can expect the ramp to
// take abs(end_value - start_value) / 25 steps on average.
local task ramp_channel(int unsigned channel, adc_value_t start_value, adc_value_t end_value);
adc_ctrl_channel_ramp_vseq vseq = adc_ctrl_channel_ramp_vseq::type_id::create("vseq");
vseq.push_pull_cfg = cfg.m_adc_push_pull_cfg[channel];
vseq.push_pull_ev = cfg.m_adc_push_pull_ev[channel];
if (!vseq.randomize() with {
vseq.ramp_start == start_value;
vseq.ramp_end == end_value;
vseq.ramp_step_min == 0;
vseq.ramp_step_max == 50;
}) begin
`uvm_fatal(`gfn, "Failed to randomise ramp vseq")
end
vseq.start(null);
endtask

// Ramp all channels in parallel from start_value to end_value
local task ramp_channels(adc_value_t start_value, adc_value_t end_value);
fork begin : isolation_fork
for (int i = 0; i < ADC_CTRL_CHANNELS; i++) begin
automatic int i_ = i;
fork ramp_channel(i_, start_value, end_value); join_none
end
wait fork;
end join
endtask

task run_iteration();
// Make sure ADC is off
csr_wr(ral.adc_en_ctl, 'h0);

// Set up the adc_ctrl registers
configure_adc_ctrl();

// Clear interrupt status reg
csr_wr(ral.adc_intr_status, '1);

// Check interrupt status is cleared
csr_rd_check(.ptr(ral.adc_intr_status), .compare_value(0),
.err_msg(called_from(`__FILE__, `__LINE__)));

// Start ADC
ral.adc_en_ctl.adc_enable.set(1);
case (cfg.testmode)
AdcCtrlTestmodeOneShot: begin
ral.adc_en_ctl.oneshot_mode.set(1);
ral.adc_pd_ctl.lp_mode.set(0);
end
AdcCtrlTestmodeNormal: begin
ral.adc_en_ctl.oneshot_mode.set(0);
ral.adc_pd_ctl.lp_mode.set(0);
end
AdcCtrlTestmodeLowpower: begin
ral.adc_en_ctl.oneshot_mode.set(0);
ral.adc_pd_ctl.lp_mode.set(1);
end
default: `uvm_fatal(`gfn, "Undefined test mode")
endcase
csr_wr(ral.adc_pd_ctl, ral.adc_pd_ctl.get());
csr_wr(ral.adc_en_ctl, ral.adc_en_ctl.get());

// Hook to do things immediately after the adc_ctrl is enabled
post_adc_ctrl_enable();

// Send randomized ramp on all channels - rising
ramp_channels(0, adc_value_t'('1));

// Send randomized ramp on all channels - falling
ramp_channels(adc_value_t'('1), 0);

// Now turn off ADC_CTRL
adc_ctrl_off();

// FSM reset to synchronise RTL & model
do_adc_fsm_reset();
endtask

task body();
for(int unsigned i = 1; i <= num_trans; i++) begin
// Re-randomize configuration if enabled and this is after the first iteration
if (i > 1 && !cfg.filters_fixed) `DV_CHECK_RANDOMIZE_FATAL(cfg)

run_iteration();
end
// A short delay to allow all CDC to complete
cfg.clk_aon_rst_vif.wait_clks($urandom_range(10, 15));
cfg.clk_aon_rst_vif.wait_clks(10);
endtask : body

// Check the status registers after every ADC sample (all channels)
Expand All @@ -126,5 +137,4 @@ class adc_ctrl_filters_polled_vseq extends adc_ctrl_base_vseq;
// Hook to do things immediately after the adc_ctrl is enabled
virtual task post_adc_ctrl_enable();
endtask

endclass : adc_ctrl_filters_polled_vseq
111 changes: 0 additions & 111 deletions hw/ip/adc_ctrl/dv/env/seq_lib/adc_ctrl_random_ramp_vseq.sv

This file was deleted.

Loading
Loading