问题
I am creating UVM VIP which is able to switch its clock polarity. Clocking block is used in the interface. For example, a monitor should sample the data using posedge or negedge of incoming clock depending on UVM configuration - and this polarity change can happen on the fly.
This can be implemented as follows:
// In the interface, two clocking blocks are defined
// one for posedge (passive_cb), one for negedge (passive_cbn).
task wait_clock_event();
if (cfg.pol == 0) @vif.passive_cb;
else @vif.passive_cbn;
endtask
task sample_data();
if (cfg.pol == 0) pkt.data = vif.passive_cb.data;
else pkt.data = vif.passive_cbn.data;
endtask
task run();
wait_clock_event();
sample_data();
endtask
This seems to work but waste code lines and prone to error.
Is there any better solution?
回答1:
Assuming the monitor has exclusive access to the clocking block, you could consider modifying clocking event in the interface with the iff
qualifier.
bit pol;
clocking passive_cb @(posedge clk iff !pol, negedge clk iff pol);
input data;
endclocking
There is a potential race condition if pol
changes in the same timestep as the target clock polarity.
Your monitor code would then include a set function and other tasks can be simplified to us only one clocking block.
function void set_vifcb_pol();
vif.pol = cfg.pol;
endfunction
task wait_clock_event();
@vif.passive_cb;
endtask
task sample_data();
pkt.data = vif.passive_cb.data;
endtask
task run();
set_vifcb_pol();
wait_clock_event();
sample_data();
endtask
来源:https://stackoverflow.com/questions/56949594/changing-clocking-block-clock-polarity-on-the-fly