Hi,
I built my own agent using UVM methodology when I send traffic towards the DUT the first packet is not aligned to the clock, it starts in the middle of the clock, while the next transactions are synchronized to the clock.
what can be the reason? (I don’t use clocking blocks in my interface if it can help please instruct how to use it correctly)
Thanks!
In reply to moshiko:
Are you synchronizing your first transaction with clock in driver?
In reply to yourcheers:
I add before the first transaction @(posedge clk) but it doesn’t help. if I add @(posedge clk) before I drive the signals (and therefore it happens before any transaction) it get synchronized but then I can’t push b2b transaction because the waiting of the clock before putting the transaction on the lines
In reply to moshiko:
What do you mean by “the middle of the clock”—the opposite clock edge? or some other clock? It has to be synchronized to something that comes before you send your first packet. You will have to trace back the code that comes before it.
In reply to dave_59:
Thanks for you answer!
yes “the middle of the clock” means the opposite clock edge. (the valid lasts for half clock cycle).
How do I do such sync?
Thanks again!
In reply to moshiko:
This is going to be very difficult to debug without seeing more code. Normally your driver code is only synchronized to one clock event.
task my_driver::run_phase(uvm_phase phase);
forever @(posedge clk) begin
if (seq_item_port.try_next_item(req)) begin
......
.. driving logic ..
......
seq_item_port.item_done();
end
// go back and wait for next cycle
end
endtask : run_phase
You will need to explain how your code deviates from that.
In reply to dave_59:
here is my original code:
virtual task run_phase(uvm_phase phase);
`msg_uvm(UVM_LOW, "Reset done ...")
//For some reason this synchronisation below is required here otherwise VCS will not
//drive signals at all ... :-0
// @(pins.driver_cb);
if (active_mode) begin
@(posedge trgt_if.clk);
forever
begin
seq_item_port.get_next_item(req);
drive_pkt_txn(req);
seq_item_port.item_done();
end
end
endtask
in this case as I said the there are b2b transaction when the first on starts at the opposite clock edge
I’ve change it to the next:
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
`msg_uvm(UVM_LOW, "Connect phase complete ...") // Driver has to be derived from ovm_driver not intc_component
endfunction
// Get sequence items from sequencer
virtual task run_phase(uvm_phase phase);
`msg_uvm(UVM_LOW, "Reset done ...")
//For some reason this synchronisation below is required here otherwise VCS will not
//drive signals at all ... :-0
// @(pins.driver_cb);
if (active_mode) begin
forever @(posedge trgt_if.clk)
begin
seq_item_port.get_next_item(req);
drive_pkt_txn(req);
seq_item_port.item_done();
end
end
endtask
extern task drive_pkt_txn(itp_trgt_seq_item txn);
endclass: itp_trgt_driver
and now the first transaction still starts at the opposite edge but there is one cycle of idleness between each two transactions…
In reply to moshiko:
You initially said that you do not use clocking blocks, but now I see that you are using them @(pins.driver_cb) in the latest example. It’s usually a bad idea to mix the use of clocking blocks events with other events like @(posedge trgt_if.clk). Without knowing how these two clocks are related it will be difficult to help you.
In reply to dave_59:
Maybe I wasn’t explaining myself well:
When I said that I don’t use clocking blocks I meant that I don’t have a clocking block in the interface (something like this):
clocking ck1(@posedge clk)
default input #5ns output #2ns;
input signal#1, signal#2,…, signal#n
output signal#n+1…
endclocking
I do have a clock signal in the interface.
Now,
My original code (in the driver) looks like:
@(posedge trgt_if.clk);
forever
begin
seq_item_port.get_next_item(req);
if.sig#1 <= pkt.sig#n1;
…
if.sig#n <= pkt.sig#n;
@(posedge trgt_if.clk);
seq_item_port.item_done();
end
your solution to wait one cycle in the beginning of the forever loop didn’t solve my issue the first transaction still starts in the middle of the clock, but now I can’t send b2b transactions (I have on cycle waiting before new transaction as a consequence of adding the @(posedge trgt_if.clk) after the ‘forever’)
I found this semi solution:
if I add the @(posedge trgt_if.clk) right after the ‘seq_item_port.get_next_item(req)’ line instead of right after the ‘forever’ the first transaction is aligned to the clock but I still can’t send b2b transaction since the @(posedge trgt_if.clk) makes a gap of one cycle between two adjacent transactions
I hope I was clear,
Thanks!