vmm example — atomic gen

`timescale 1ns/1ns
//interface
interface bus(input clk);
logic [7:0] addr;
logic [31:0] data;

clocking cb @(posedge clk);
default input #1ns output #1ns;
output addr;
output data;
endclocking

modport master (clocking cb);

endinterface

//transaction
class bus_tran extends vmm_data;

rand logic [7:0] addr;
rand logic [31:0] data;

static vmm_log log = new(“bus tran log”, “bus tran log0″);

function new();
super.new(this.log);
endfunction

virtual function string psdisplay(string prefix=””);
super.psdisplay(prefix);
$sformat(psdisplay, “%s time: %t “, psdisplay, $time);
$sformat(psdisplay, “%s addr: %h “, psdisplay, this.addr);
$sformat(psdisplay, “%s data: %h “, psdisplay, this.data);
endfunction: psdisplay

virtual function vmm_data copy(vmm_data to = null);
bus_tran cpy;

if(to == null)
cpy = new();
else begin
if(!$cast(cpy, to)) begin
`vmm_fatal(this.log, “Error to cast to to cpy”);
cpy = null;
return cpy;
end
end

super.copy_data(cpy);
cpy.addr = this.addr;
cpy.data = this.data;

return cpy;

endfunction: copy

endclass

//channel
`vmm_channel(bus_tran)
//generator
`vmm_atomic_gen(bus_tran, “bus_tran_atomic_gen”)

//driver
class bus_driver extends vmm_xactor;

virtual bus.master bus_if;
bus_tran_channel bus_ch;

function new(
virtual bus.master bus_if,
bus_tran_channel bus_ch
);
super.new(“bus_driver”, “bus_driver1”);
this.bus_if = bus_if;
this.bus_ch = bus_ch;
endfunction

task main();
bus_tran bus_tr;
bus_tran bus_tr_cpy;

super.main();

forever begin
bus_ch.get(bus_tr);
$cast(bus_tr_cpy, bus_tr.copy());
bus_tr_cpy.display();
@(bus_if.cb);
bus_if.cb.addr <= bus_tr_cpy.addr;
bus_if.cb.data <= bus_tr_cpy.data;
end
endtask

endclass

//bus_env
class bus_env extends vmm_env;

virtual bus.master bus_if;
bus_tran_atomic_gen bus_gen;
bus_driver bus_drv;
bus_tran_channel bus_ch;

function new(virtual bus.master bus_if);
super.new(“bus_env”);
this.bus_if = bus_if;
endfunction

function void build();
super.build();
bus_ch = new(“bus channel”, “bus chan0”);
bus_gen = new(“bus_gen”, 0, bus_ch);
bus_drv = new(bus_if, bus_ch);
endfunction

task start();
super.start();
fork
bus_gen.start_xactor();
bus_drv.start_xactor();
join_none
endtask

task wait_for_end();
super.wait_for_end;
this.bus_gen.notify.wait_for(bus_tran_atomic_gen::DONE);
#1000;
endtask

endclass

///////////////////////////////////////////////////////////
//test — use default
///////////////////////////////////////////////////////////
program test(bus.master bus_if);

bus_env e = new(bus_if);

initial begin
e.build();
e.bus_gen.stop_after_n_insts = 10;
e.run();
end

endprogram

//top

module top();

reg clk;

initial begin
clk = 0;
forever #10 clk = ~clk;
end

initial begin
$vcdpluson();
end

bus bus0(clk);

test test1(
bus0.master
);

dut u_dut(
.addr(bus0.addr),
.data(bus0.data)
);

endmodule

//dut

module dut(
addr,
data
);
input [7:0] addr;
input [31:0] data;
endmodule

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

4 Responses to vmm example — atomic gen

  1. alexu2595 says:

    ///////////////////////////////////////////////////////////
    //test — vmm_test without macro
    ///////////////////////////////////////////////////////////
    class bus_tran_data extends bus_tran;
    constraint data_con {
    data inside {[11:’h20]};
    }

    function new();
    super.new();
    endfunction
    endclass

    class test_1 extends vmm_test;
    bus_env env;

    function new();
    super.new(“test_1″, “Test_1″);
    endfunction

    static test_1 test_1_inst = new();
    bus_tran_data bus_tran1;

    task run(vmm_env env);
    doRun(env);
    endtask

    task doRun(vmm_env __env);
    $cast(this.env, __env);
    begin
    env.build();
    bus_tran1 = new();
    env.bus_gen.randomized_obj = bus_tran1;
    env.bus_gen.stop_after_n_insts = 10;
    env.run();
    end
    endtask
    endclass: test_1

    program test(bus.master bus_if);

    bus_tran_data bus_tran1;

    initial
    begin
    bus_env e = new(bus_if);
    vmm_test_registry::run(e);
    end

    endprogram

  2. alexu2595 says:

    ///////////////////////////////////////////////////////////
    //test — vmm_test with macro
    ///////////////////////////////////////////////////////////
    class bus_tran_data extends bus_tran;
    constraint data_con {
    data inside {[0:’h10]};
    }

    function new();
    super.new();
    endfunction
    endclass

    program test(bus.master bus_if);

    bus_tran_data bus_tran1;

    `vmm_test_begin(test_1, bus_env, “Test_1″)
    env.build();
    bus_tran1 = new();
    env.bus_gen.randomized_obj = bus_tran1;
    env.bus_gen.stop_after_n_insts = 10;
    env.run();
    `vmm_test_end(test_1)

    initial
    begin
    bus_env e = new(bus_if);
    vmm_test_registry::run(e);
    end

    endprogram

  3. alexu2595 says:

    ///////////////////////////////////////////////////////////
    //test — use new transaction class to override
    ///////////////////////////////////////////////////////////
    class bus_tran_addr extends bus_tran;

    constraint addr_con {
    addr inside {[0:’h10]};
    }

    function new();
    super.new();
    endfunction

    endclass

    program test(bus.master bus_if);

    bus_env e = new(bus_if);
    bus_tran_addr bus_tran1 = new();

    initial begin
    e.build();
    e.bus_gen.randomized_obj = bus_tran1;
    e.bus_gen.stop_after_n_insts = 10;
    e.run();
    end

    endprogram

  4. alexu2595 says:

    run cmd:
    vcs -sverilog -ntb_opts rvm +vmm_test=test_1 test.sv -R -debug_pp

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s