Skip to content

Commit 7780c6b

Browse files
committed
[dv,pwm] Parameterized channel count
Modify the DV environment to support other channel counts; until now a channel count of 6 has been assumed. Minor reformatting changes within the scoreboard. Signed-off-by: Adrian Lees <a.lees@lowrisc.org>
1 parent bbc658e commit 7780c6b

File tree

3 files changed

+35
-50
lines changed

3 files changed

+35
-50
lines changed

hw/ip/pwm/dv/env/pwm_env_pkg.sv

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,14 @@ package pwm_env_pkg;
6262
bit [15:0] X;
6363
} blink_param_t;
6464

65-
// The index of a multi-reg is given by the last character of the name, since there are fewer
66-
// than ten channels.
67-
function automatic int get_multireg_idx(string name);
68-
string s = name.getc(name.len - 1);
69-
return s.atoi();
65+
// The index of a multi-reg is given by the last character(s) of the name. The number of PWM
66+
// channels is parameterized.
67+
function automatic int unsigned get_multireg_idx(string name);
68+
int str_len = name.len();
69+
// Note: this extracts the final two characters which are either '_y' or 'xy',
70+
// and because '_' is permitted in (System)Verilog numbers, it works for 0-99
71+
string index_str = name.substr(str_len-2, str_len-1);
72+
return index_str.atoi();
7073
endfunction
7174

7275
// Package sources

hw/ip/pwm/dv/env/pwm_scoreboard.sv

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,16 @@ endfunction
7171

7272
task pwm_scoreboard::run_phase(uvm_phase phase);
7373
super.run_phase(phase);
74-
75-
// TODO: Decide whether we want to leave the processes running.
76-
forever begin
77-
`DV_SPINWAIT_EXIT(
74+
if (cfg.en_scb) begin
75+
// Create one checker process for each PWM output.
76+
foreach (item_fifo[channel]) begin
77+
// Ensure that the newly-created process does not see changes to the 'channel' variable when
78+
// starting.
79+
automatic int ch = channel;
7880
fork
79-
compare_trans(0);
80-
compare_trans(1);
81-
compare_trans(2);
82-
compare_trans(3);
83-
compare_trans(4);
84-
compare_trans(5);
85-
join,
86-
@(negedge cfg.clk_rst_vif.rst_n),
87-
)
81+
compare_trans(ch);
82+
join_none
83+
end
8884
end
8985
endtask
9086

@@ -100,6 +96,7 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
10096
string ral_name);
10197
string txt;
10298
uvm_reg csr;
99+
int unsigned idx;
103100
bit [TL_DW-1:0] reg_value;
104101
bit do_read_check = 1'b1;
105102
bit write = item.is_write();
@@ -112,13 +109,13 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
112109
if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin
113110
csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr);
114111
`DV_CHECK_NE_FATAL(csr, null)
112+
// Extract register index indicating the channel number.
113+
idx = get_multireg_idx(csr.get_name());
115114
end else begin
116115
`uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr))
117116
end
118117

119118
if (addr_phase_write) begin
120-
string csr_name = csr.get_name();
121-
122119
// if incoming access is a write to a valid csr, then make updates right away
123120
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
124121

@@ -136,7 +133,7 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
136133
channel_en = item.a_data[PWM_NUM_CHANNELS-1:0];
137134
foreach (channel_en[ii]) begin
138135
if (channel_en[ii] & !prev_en[ii]) begin
139-
`uvm_info(`gfn, $sformatf("detected enabling of channel[%d]", ii), UVM_HIGH)
136+
`uvm_info(`gfn, $sformatf("detected enabling of channel[%0d]", ii), UVM_HIGH)
140137
// Set up the prediction state for this channel.
141138
blink_cnt[ii] = blink[ii].X;
142139
blink_state[ii] = CycleA;
@@ -146,7 +143,7 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
146143
// enabled with an arbitrary phase relationship to the shared phase counter.
147144
ignore_state_change[ii] = SettleTime;
148145
end
149-
txt = $sformatf("\n Channel[%d] : %0b", ii, channel_en[ii]);
146+
txt = $sformatf("\n Channel[%0d] : %0b", ii, channel_en[ii]);
150147
if (cfg.en_cov) begin
151148
cov.lowpower_cg.sample(cfg.clk_rst_vif.clk_gate,
152149
$sformatf("cfg.m_pwm_monitor_[%0d]_vif", ii));
@@ -176,52 +173,37 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
176173
"invert": begin
177174
invert = item.a_data[PWM_NUM_CHANNELS-1:0];
178175
foreach (invert[ii]) begin
179-
txt = {txt, $sformatf("\n Invert Channel[%d] : %0b",ii, invert[ii])};
176+
txt = {txt, $sformatf("\n Invert Channel[%0d] : %0b", ii, invert[ii])};
180177
end
181178
`uvm_info(`gfn, $sformatf("Setting channel Inverts %s ", txt), UVM_HIGH)
182179
end
183180

184-
"pwm_param_0",
185-
"pwm_param_1",
186-
"pwm_param_2",
187-
"pwm_param_3",
188-
"pwm_param_4",
189-
"pwm_param_5": begin
190-
int idx = get_multireg_idx(csr_name);
181+
// PWM_PARAM_<i> registers; channel count is parameterized.
182+
$sformatf("pwm_param_%0d", idx): begin
191183
channel_param[idx].PhaseDelay = get_field_val(ral.pwm_param[idx].phase_delay,
192184
item.a_data);
193185
channel_param[idx].HtbtEn = get_field_val(ral.pwm_param[idx].htbt_en, item.a_data);
194186
channel_param[idx].BlinkEn = get_field_val(ral.pwm_param[idx].blink_en, item.a_data);
195-
txt = $sformatf("\n Setting Param for channel[%d]", idx);
187+
txt = $sformatf("\n Setting Param for channel[%0d]", idx);
196188
txt = {txt, $sformatf("\n ----| Phase Delay %0h", channel_param[idx].PhaseDelay)};
197189
txt = {txt, $sformatf("\n ----| Heart Beat enable: %0b", channel_param[idx].HtbtEn) };
198190
txt = {txt, $sformatf("\n ----| Blink enable: %0b", channel_param[idx].BlinkEn) };
199-
`uvm_info(`gfn, $sformatf("Setting Channel Param for CH[%d], %s",idx, txt), UVM_HIGH)
191+
`uvm_info(`gfn, $sformatf("Setting Channel Param for CH[%0d], %s", idx, txt), UVM_HIGH)
200192
end
201193

202-
"duty_cycle_0",
203-
"duty_cycle_1",
204-
"duty_cycle_2",
205-
"duty_cycle_3",
206-
"duty_cycle_4",
207-
"duty_cycle_5": begin
208-
int idx = get_multireg_idx(csr_name);
194+
// DUTY_CYCLE_<i> registers; channel count is parameterized.
195+
$sformatf("duty_cycle_%0d", idx): begin
209196
duty_cycle[idx].A = get_field_val(ral.duty_cycle[idx].a, item.a_data);
210197
duty_cycle[idx].B = get_field_val(ral.duty_cycle[idx].b, item.a_data);
211-
`uvm_info(`gfn, $sformatf("\n Setting channel[%d] duty cycle A:%0h B:%0h", idx,
198+
`uvm_info(`gfn, $sformatf("\n Setting channel[%0d] duty cycle A:%0h B:%0h", idx,
212199
duty_cycle[idx].A ,duty_cycle[idx].B), UVM_HIGH)
213200
end
214201

215-
"blink_param_0",
216-
"blink_param_1",
217-
"blink_param_2",
218-
"blink_param_3",
219-
"blink_param_4",
220-
"blink_param_5": begin
221-
int idx = get_multireg_idx(csr_name);
202+
// BLINK_PARAM_<i> registers; channel count is parameterized.
203+
$sformatf("blink_param_%0d", idx): begin
222204
blink[idx].X = get_field_val(ral.blink_param[idx].x, item.a_data);
223205
blink[idx].Y = get_field_val(ral.blink_param[idx].y, item.a_data);
224-
`uvm_info(`gfn, $sformatf("\n Setting channel[%d] Blink X:%0h Y:%0h", idx,
206+
`uvm_info(`gfn, $sformatf("\n Setting channel[%0d] Blink X:%0h Y:%0h", idx,
225207
blink[idx].X ,blink[idx].Y), UVM_HIGH)
226208
end
227209

hw/ip/pwm/dv/env/seq_lib/pwm_heartbeat_wrap_vseq.sv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class pwm_heartbeat_wrap_vseq extends pwm_rand_output_vseq;
1010
// Enable heartbeat (since we're trying to make it wrap, so it definitely needs to be enabled)
1111
extern constraint with_heartbeat_c;
1212

13-
extern function new (string name="");
13+
extern function new(string name = "");
1414

1515
// This overrides a function from pwm_base_vseq. We want to choose a "maximal" duty cycle, where A
1616
// and B are near the endpoints of the 16 bit data type (to make it likely that the increment will
@@ -29,7 +29,7 @@ constraint pwm_heartbeat_wrap_vseq::with_heartbeat_c {
2929
}
3030
}
3131

32-
function pwm_heartbeat_wrap_vseq::new (string name);
32+
function pwm_heartbeat_wrap_vseq::new(string name = "");
3333
super.new(name);
3434
endfunction
3535

0 commit comments

Comments
 (0)