Hi I’m SystemVerilog novice. For starter, I’m building a very simple testbench to verify a very simple RTL. I just want to get myself used to the structure, so i guess the complexity of rtl doesn’t matter (for now).
I’ve already built testbench.sv, testcase.sv, packet.sv, switch_interface.sv, and monitor.sv. Inside the env.sv, i have a run task that calls driver.send_packet() first and monitor.collect_packet() later. This implies that the output packets will be collected after packets have already sent in. they executes in order, serially. Is there a way to make the them executing concurrently and simultaneously so that packets can be collected and sent and the same time? I think i need some code-restructuring but don’t know where to start…
My code is here: https://drive.google.com/file/d/0B5eA_2-8U5JnaHF5aUdsTHV0NEE/view?usp=sharing
Also the env.sv
I would highly recommend that you use the UVM as part of your learning process. You are duplicating many of the UVM features (driver, monitor, environment, etc.) that have been designed and implemented by experts with many years of verification experience, and are encountering issues that have already been addressed in the most efficient manner.
While you might consider it a good learning experience to write your own testbench methodology, you could at least refer to the UVM source code to see how specific challenges have been implemented.
Hi
For the sake of completeness, an example of where the task forks to perform the two subtasks in parallel and then waits until they have both finished is below. You could also replace “join” with “join_none” to have the main task exit immediately, leaving the two subtasks to run completely asynchronously.
However, as has already been suggested, a purer UVM style of independent drivers and monitors would be a better investment of your time. While knowledge of fork/join is very useful, it leads to more convoluted and non-standard coding in this case with more potential for bugs or hidden dependencies which mean that the DUT is not stimulated as randomly as possible.
task run(int num_packet=4);
for(int i=0; i<num_packet;i++) begin
@(posedge vi.clk)
$display("==========time=%0d:Sending packet #%0d==========",$time, i+1);
fork
begin
drv.send_packet();
$display("==========time=%0d:Sent packet #%0d=========",$time, i+1);
end
begin
mon.collect_packet();
$display("==========time=%0d:Collected packet #%0d=========",$time, i+1);
end
join
endtask
That was a very thorough answer. Thx a ton!
Yeah I am actually learning UVM, slowly. Currently I reading this great tutorial UVM Guide for Beginners – Pedro Araújo not too hard to understand.