Hi,
I have two different clock frequency 65MHz and 53.16MHz, at interface clocking block (for driver). I wanted to add both the clocks in clocking block sensitivity list.
So how can I approach that scenario ? Your advice and guidance is highly appreciated Thanks.
In reply to Yeptho:
This seems like a very unusual situation.
A SystemVerilog clocking block can only be associated with a single clock. You can either use the output of a multiplexer that selects between the two clocks, or you can create two clocking blocks that drive the same signals.
In reply to Yeptho:
Hi,
I have two different clock frequency 65MHz and 53.16MHz, at interface clocking block (for driver). I wanted to add both the clocks in clocking block sensitivity list.
So how can I approach that scenario ? Your advice and guidance is highly appreciated Thanks.
The key question is if you are using these clocks concurrently or as alternatives.
In reply to chr_sue:
In reply to Yeptho:
The key question is if you are using these clocks concurrently or as alternatives.
Hi chr_sue, I have to use in concurrent manner, If you can please help me with some example code will be really helpful.
In reply to Yeptho:
What you are describing looks like a driver protocol depending on 2 clocks at the same time.
Can you please show some more details.
In reply to Yeptho:
interface my_itf(input clk1,clk2);
wire signal;
clocking cb1 @(posedge clk1);
output signal;
endclocking
clocking cb2 @(posedge clk2);
output signal;
endclocking
endinterface
Assuming you have a virtual interface handle vif, you would drive the signal with either
vif.cb1.signal <= something;
// or
vif.cb2.signal <= something;
In reply to chr_sue:
Hi Chr_sue, Here’s my sample code
// my_Sequence
task body();
if (pkt_tx.rd_file == 1'b1) begin
assert(pkt_tx.randomize());
end
else begin
#1009.700ns $readmemh("./image_2_hex.txt", mem_array);
if(vif.i_reset_n==1'b1) begin
for(int i=0;i<2000; i++) begin
@(posedge vif.i_Pixel_clock);
pkt_tx.i_pixel_data <= mem_array[i];
end
start_item(pkt_tx);
pkt_tx.signal1 <= 4'h4 ;
pkt_tx.signal2 <= 4'h5 ;
// .
// .
finish item(pkt_tx);
end
endtask
// Driver :
//Below drive_pixel and drive_framer task are mine
task drive_pixel(packet_trans pkt_tx);
vif.drv_pxl_cb.i_pixel_data <= pkt_tx.i_pixel_data ;
vif.drv_pxl_cb.signal1 <= pkt_tx.signal1 ;
// .
// .
endtask
task drive_framer(packet_trans pkt_tx);
vif.drv_frmr_cb.signal2 <= pkt_tx.signal2;
// .
// .
endtask
//-------------Driver run_phase ------------//
seq_item_port.get_next_item(pkt_tx);
wait(vif.i_reset_n == 1'b1)
begin
fork
@(posedge vif.i_Pixel_clock)drive_pixel(pkt_tx);
@(posedge vif.i_sys_clock)drive_framer(pkt_tx);
join
end
seq_item_port.item_done();
For the clocking block in the interface, I have implemented as shown by Dave, with respect to two different clock
In reply to Yeptho:
You shoule bever deal with clock and reset in the sequence. This makes your sequences unreusable and slows down the simulation.
Is this really true you are processing the pixel and the frame data concurrently?
How is yor DUT reacting?
In reply to chr_sue:
Hi chr_sue, I need to pass the backdoor read image_2_hex.txt value to i_pixel_data with respect to i_Pixel_clock so I’m depending on vif in sequence. If there’s any other way Please suggest.
Well my DUT is responding to the values which are driven from sequence (example : signal1 and signal2) but for i_pixel_data which is pass from sequence, it is not responding by DUT.
In reply to Yeptho:
In the sequencer/sequence only the order of data is relevant. Any timing will be done in the driver.
In reply to dave_59:
Hi Dave, Implemented clocking block by following your example.
I have driven the signals with respect to clocking block from Driver and DUT has responded, except the backdoor read file which is not able to drive from driver to DUT.
So can you please point out where i did gaffe in the code.
In reply to chr_sue:
Hi Chr_sue, like you said timing related to do in driver, So a task is created for reading the text file in the driver class.
//task for reading txt file in driver
task read_image_2_hex();
#1009.700ns $readmemh("./image_2_hex.txt", this.temp_mem);
if(vif.i_pixel_enable==1'b1) begin
for(int i=0;i<2000;i++) begin
@(posedge vif.i_Pixel_clock);
arinc_818_tx.i_pixel_data <= this.temp_mem[i];
$display("read_file_drv --> temp_mem[%0d] = %h",i,this.temp_mem[i]);
$display("read_file_drv --> i_pixel_data[%0d] = %h",i,arinc_818_tx.i_pixel_data[i]); //not able to take the value from temp_mem to i_pixel_data
end
end
endtask
// driver task run_phase
wait(vif.i_reset_n == 1'b1) begin :B3
fork
@(posedge vif.i_Pixel_clock) drive_pxl(arinc_818_tx);
read_image_2_hex();
@(posedge vif.i_sys_clock) drive_frmr(arinc_818_tx);
join
end :B3
endclass :driver
//Console Output Report
.
.
read_file_drv → temp_mem[1998] = 67503e
read_file_drv → i_pixel_data[1998] = 0
read_file_drv → temp_mem[1999] = 67513c
read_file_drv → i_pixel_data[1999] = 0
read_file_drv → temp_mem[2000] = 6e5843
read_file_drv → i_pixel_data[2000] = 0
In reply to Yeptho:
This is not enough code to see where your problem is.
Why do you delay the readmemh and you should do this from outside your driver task.
In reply to chr_sue:
Hi Chr_sue, thank you for pointing out the reading file of .txt outside the driver task.
I’m passing the .txt with the help of vif, some data are missed as well as some are captured in the waveforms. BTW thank you and Dave for the valuable inputs.
cheers,
Are there any limitations to using multiple clocking blocks, each using a different clock edge, within a driver or monitor?
No limitations. But that does not mean no problems. Hard to say with such a general question.
I am finding that even if I use a clocking block with the negedge, the transaction data is applied to the DUT on the posedge, which is not expected. So obviously, there is a ghost in the machine.