Is there a way that a virtual sequence can directly call a vr_ad
write_reg
or read_reg
macro without me having to create a vr_ad_sequence
that does the same thing?
To illustrate more clearly, here is my current implementation:
<'
extend vr_ad_sequence_kind : [WR_DMA_POLL];
extend WR_DMA_POLL vr_ad_sequence {
!dma_poll : DMA_POLL vr_ad_reg;
body() @driver.clock is only {
write_reg dma_poll val 0xdeadbeef;
};
};
extend MAIN soc_tb_virtual_sequence {
!write_dma_poll : WR_DMA_POLL vr_ad_sequence;
body() @driver.clock is only {
message(LOW, "TEST START");
do write_dma_poll on driver.reg_driver;
};
};
'>
Why can't it be, or is it possible to implement this way?
extend MAIN soc_tb_virtual_sequence {
!dma_poll : DMA_POLL vr_ad_reg;
body() @driver.clock is only {
message(LOW, "TEST START");
write_reg {.dest_driver == driver.reg_driver} dma_poll;
read_reg {.dest_driver == driver.reg_driver} dma_poll;
};
};
Thank you in advance for any explanation.
This is possible starting with vr_ad 13.20 (or maybe slightly older). You almost had it in your question. The correct syntax is:
extend MAIN soc_tb_virtual_sequence {
!dma_poll : DMA_POLL vr_ad_reg;
body() @driver.clock is only {
message(LOW, "TEST START");
write_reg {.driver == driver.reg_driver} dma_poll;
read_reg {.driver == driver.reg_driver} dma_poll;
};
};
The first set of {...}
delimits the operation generate block, where you can constrain how to access the register. These constraints will be passed to the vr_ad_operation
that gets generated as part of the access.