@@ -71,20 +71,16 @@ endfunction
71
71
72
72
task pwm_scoreboard::run_phase (uvm_phase phase);
73
73
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;
78
80
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
88
84
end
89
85
endtask
90
86
@@ -100,6 +96,7 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
100
96
string ral_name);
101
97
string txt;
102
98
uvm_reg csr;
99
+ int unsigned idx;
103
100
bit [TL_DW - 1 : 0 ] reg_value;
104
101
bit do_read_check = 1'b1 ;
105
102
bit write = item.is_write ();
@@ -112,13 +109,13 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
112
109
if (csr_addr inside { cfg.ral_models[ral_name].csr_addrs} ) begin
113
110
csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset (csr_addr);
114
111
`DV_CHECK_NE_FATAL (csr, null )
112
+ // Extract register index indicating the channel number.
113
+ idx = get_multireg_idx (csr.get_name ());
115
114
end else begin
116
115
`uvm_fatal (`gfn , $sformatf (" Access unexpected addr 0x%0h " , csr_addr))
117
116
end
118
117
119
118
if (addr_phase_write) begin
120
- string csr_name = csr.get_name ();
121
-
122
119
// if incoming access is a write to a valid csr, then make updates right away
123
120
void '(csr.predict (.value (item.a_data), .kind (UVM_PREDICT_WRITE ), .be (item.a_mask)));
124
121
@@ -136,7 +133,7 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
136
133
channel_en = item.a_data[PWM_NUM_CHANNELS - 1 : 0 ];
137
134
foreach (channel_en[ii]) begin
138
135
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 )
140
137
// Set up the prediction state for this channel.
141
138
blink_cnt[ii] = blink[ii].X ;
142
139
blink_state[ii] = CycleA;
@@ -146,7 +143,7 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
146
143
// enabled with an arbitrary phase relationship to the shared phase counter.
147
144
ignore_state_change[ii] = SettleTime;
148
145
end
149
- txt = $sformatf (" \n Channel[%d ] : %0b " , ii, channel_en[ii]);
146
+ txt = $sformatf (" \n Channel[%0d ] : %0b " , ii, channel_en[ii]);
150
147
if (cfg.en_cov) begin
151
148
cov.lowpower_cg.sample (cfg.clk_rst_vif.clk_gate,
152
149
$sformatf (" cfg.m_pwm_monitor_[%0d ]_vif" , ii));
@@ -176,52 +173,37 @@ task pwm_scoreboard::process_tl_access(tl_seq_item item,
176
173
" invert" : begin
177
174
invert = item.a_data[PWM_NUM_CHANNELS - 1 : 0 ];
178
175
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])} ;
180
177
end
181
178
`uvm_info (`gfn , $sformatf (" Setting channel Inverts %s " , txt), UVM_HIGH )
182
179
end
183
180
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
191
183
channel_param[idx].PhaseDelay = get_field_val (ral.pwm_param[idx].phase_delay,
192
184
item.a_data);
193
185
channel_param[idx].HtbtEn = get_field_val (ral.pwm_param[idx].htbt_en, item.a_data);
194
186
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);
196
188
txt = { txt, $sformatf (" \n ----| Phase Delay %0h " , channel_param[idx].PhaseDelay)} ;
197
189
txt = { txt, $sformatf (" \n ----| Heart Beat enable: %0b " , channel_param[idx].HtbtEn) } ;
198
190
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 )
200
192
end
201
193
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
209
196
duty_cycle[idx].A = get_field_val (ral.duty_cycle[idx].a, item.a_data);
210
197
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,
212
199
duty_cycle[idx].A ,duty_cycle[idx].B ), UVM_HIGH )
213
200
end
214
201
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
222
204
blink[idx].X = get_field_val (ral.blink_param[idx].x, item.a_data);
223
205
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,
225
207
blink[idx].X ,blink[idx].Y ), UVM_HIGH )
226
208
end
227
209
0 commit comments