Hi,
when I try to sample packets from my monitor using the clocking block I declared in my Interface (pkt.value = vif.cb.value) I get a compilation error.
is it allowed to sample signals using clocking blocks? if so how do I do it?
Thanks,
Moshiko
Hi,
when I try to sample packets from my monitor using the clocking block I declared in my Interface (pkt.value = vif.cb.value) I get a compilation error.
is it allowed to sample signals using clocking blocks? if so how do I do it?
Thanks,
Moshiko
In reply to moshiko:
It is difficult to determine with the little information you provided. Please provide more code along with the exact error message you are getting.
In reply to cgales:
my interface:
interface ram_interface(input bit clk);
logic[4-1 : 0] addr;
logic[32-1: 0] data;
logic cs ;
logic we ;
logic oe ;
clocking cb @(posedge clk);
output #50ps addr,cs,we,oe;
input #2ps output #50ps data;
endclocking
modport TB (input clk, clocking cb);
endinterface: ram_interface
my monitor:
class ram_monitor extends uvm_monitor;
`uvm_component_utils(ram_monitor)
function new(name = "ram_monitor", uvm_component parent);
super.new(name, parent);
endfunction:new
virtual ram_interface vif;
ram_seq_item pkt;
uvm_analysis_port #(ram_seq_item) mon_port;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!(uvm_config_db #(virtual ram_interface)::get(this, "*", "intf", vif)))
`uvm_fatal(get_type_name(), $psprintf("couldn't get an interface"))
mon_port = new("mon_port", this);
endfunction:build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
endfunction:connect_phase
task run_phase(uvm_phase phase);
super.run_phase(phase);
forever begin
@(vif.cb);
if(vif.cs == 1 && vif.we == 1)
begin
pkt = ram_seq_item::type_id::create("pkt");
pkt.addr = vif.addr;
pkt.data = vif.data;
pkt.cs = vif.cs;
pkt.we = vif.we;
pkt.oe = vif.oe;
mon_port.write(pkt);
end
if(vif.cs == 1 && vif.oe == 1)
begin
pkt = ram_seq_item::type_id::create("pkt");
pkt.addr = vif.addr;
pkt.cs = vif.cs;
pkt.we = vif.we;
pkt.oe = vif.oe;
@(vif.cb);
pkt.data = vif.data;
mon_port.write(pkt);
end
end
endtask: run_phase
endclass:ram_monitor
I mean that pkt.addr = vif.cb.addr is not allowed while in my driver when I drive the DUT using my interface vif.cb.addr <= pkt.addr is allowed.
Thanks!
In reply to moshiko:
Several issues:
In reply to cgales:
Thanks for answering!
in the last point you raise you meant that in case of driving I need to use ‘<=’ instead of ‘=’?
If so, that’s exactly what I’m doing in my driver.
another question that I have regrading that(I saw different answer for this but I didn’t completely understood), why when we sampling we use blocking assignment and when we are driving we use non blocking assignments (I know it’s related to racing conditions but I can’t understand this completely, if you have some example I’d love to see it).
and last question regarding clocking block, when we sample a signal we sample it a bit before the clock edge, but what if in the signal’s value changes @(posedge)? it seems like we sample an old value of the signal, am I missing something?
Thanks again!
In reply to moshiko:
You sample with blocking assignments as you are putting values into a testbench structure. You assign with non-blocking assignments as the clocking block uses the output skew to assign the clocking block values to the associated signals.
Clocking blocks are designed to prevent race conditions where signals change at the same time as the clock. You are correct that the input skew will sample all values prior to the clock edge. This ensures that you get the values for all signals correctly and don’t have a mismatch of some signals that have changed and some that haven’t.