Monday, March 31, 2014

some basic systemVerilog syntax

1) Integer data types
shortint 2-state SystemVerilog data type, 16 bit signed integer
int 2-state SystemVerilog data type, 32 bit signed integer
longint 2-state SystemVerilog data type, 64 bit signed integer
byte 2-state SystemVerilog data type, 8 bit signed integer or ASCII character
bit 2-state SystemVerilog data type, user-defined vector size
logic 4-state SystemVerilog data type, user-defined vector size
reg 4-state Verilog-2001 data type, user-defined vector size
integer 4-state Verilog-2001 data type, 32 bit signed integer
time 4-state Verilog-2001 data type, 64-bit unsigned integer

2) Default values
Type Default Initial value
4 state integral ’X
2 state integral ’0
real, shortreal 0.0
Enumeration First value in the enumeration
string "" (empty string)
event New event
class null
chandle (Opaque handle) null

10) class
/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
class cpu_transaction;

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

endclass: cpu_transaction

11) program
/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] data  ;
logic        rw    ;

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

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"

program test(cpu_interface.master cpu_intf);

initial begin
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`include "cpu_interface.svi"
`include "test.sv"
module top;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

endmodule

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/program
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/program
SVTB  = $(TB_DIR)/test.sv
SVTB += $(TB_DIR)/top.sv

INCDIR = +incdir+/mnt/program

COMPILE_LOG_ARG = -l vcs.log

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

12) interface
/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] data  ;
logic        rw    ;

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

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"

program test(cpu_interface.master cpu_intf);

event done;

initial begin
    cpu_intf.rst_n   <= 1'b0;
    cpu_intf.cb.addr <= 8'h0;
    cpu_intf.cb.data <= 32'h0;
    cpu_intf.cb.rw   <= 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n <= 1'b1;
    @(cpu_intf.cb);
    cpu_intf.cb.addr <= 8'h1;
    cpu_intf.cb.data <= 32'h1;
    cpu_intf.cb.rw <= 1'b0;
    @(cpu_intf.cb);
    cpu_intf.cb.addr <= 8'h2;
    cpu_intf.cb.data <= 32'h2;
    cpu_intf.cb.rw <= 1'b1;
    ->done;
end

initial begin
    @done;
    #10 $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`include "cpu_interface.svi"
`include "test.sv"
module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2)
            clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/interface
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/interface
SVTB  = $(TB_DIR)/test.sv
SVTB += $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

100) transaction
/////////////////////////////////////////////
//cpu_transaction
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

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

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, data = %0h", prefix, $realtime, name, addr, data);
endfunction

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_transaction.sv"

program test();

event done;

initial begin
    cpu_transaction cpu_tran;
    cpu_tran = new();
    repeat(10) begin
        if(!cpu_tran.randomize()) begin
            $display("Error to randomize cpu_tran");
        end
        cpu_tran.display();
        #1;
    end
    ->done;
end

initial begin
    @done;
    #10 $finish();
end

endprogram
`endif

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/transaction
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/transaction
SVTB  = $(TB_DIR)/test.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

101) generator
/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

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

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, data = %0h", prefix, $realtime, name, addr, data);
endfunction

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    for(int i=0; i<run_for_n_trans; i++) begin
        cpu_transaction cpu_tran = new();
        if(!cpu_tran.randomize()) begin
            $display("Error to randomize cpu_tran");
        end
        out_box.put(cpu_tran);
    end
    ->done;
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_generator.sv"
`include "cpu_define.sv"

program test();

event done;
cpu_tran_mbox mbox = new();
cpu_generator cpu_gen;

initial begin
    cpu_gen = new("CPU Generator", mbox);
    cpu_gen.run_for_n_trans = 10;
    cpu_gen.start();
end

initial begin
    cpu_transaction cpu_tran;
    forever begin
        mbox.get(cpu_tran);
        cpu_tran.display();
    end
end

initial begin
    @cpu_gen.done;
    #10 $finish();
end

endprogram
`endif

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/generator
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/generator
SVTB  = $(TB_DIR)/test.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

102) driver
/////////////////////////////////////////////
/////////////////////////////////////////////
//driver and monitor in the same bfm
/////////////////////////////////////////////
/////////////////////////////////////////////

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

rand logic [7:0] addr;
rand logic [31:0] data;
rand logic rw;
string name;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, data = %0h, rw = %d", prefix, $realtime, name, addr, data, rw);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] data  ;
logic        rw    ;

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

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        for(int i=0; i<run_for_n_trans; i++) begin
            cpu_transaction cpu_tran = new();
            if(!cpu_tran.randomize()) begin
                $display("Error to randomize cpu_tran");
            end
            out_box.put(cpu_tran);
        end
        ->done;
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.data <= cpu_tran.data;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            @(cpu_intf.cb);
            cpu_intf.cb.addr <= 8'h0 ;
            cpu_intf.cb.data <= 32'h0 ;
            cpu_intf.cb.rw   <= 1'b1 ;
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"

program test(cpu_interface.master cpu_intf);

event done;
cpu_tran_mbox mbox = new();
cpu_generator cpu_gen;
cpu_driver    cpu_drv;

initial begin
    cpu_gen = new("CPU Generator", mbox);
    cpu_drv = new("CPU Driver", mbox, cpu_intf);

    cpu_gen.run_for_n_trans = 10;
    cpu_gen.start();
    cpu_drv.start();

    @cpu_gen.done;
    repeat(100) @(cpu_intf.cb);
    $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/driver
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/driver
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

103) monitor
/////////////////////////////////////////////
//dut.v
/////////////////////////////////////////////
`timescale 1ns/1ps

module dut(
    clk   ,
    rst_n ,
    addr  ,
    din   ,
    rw    ,
    dout
);

input         clk   ;
input         rst_n ;
input  [7:0 ] addr  ;
input  [31:0] din   ;
input         rw    ;

output [31:0] dout  ;

wire        clk   ;
wire        rst_n ;
wire [7:0 ] addr  ;
wire [31:0] din   ;
wire        rw    ;

reg  [31:0] dout  ;

wire        write ;
wire        read  ;

reg  [31:0] config_reg ;
reg  [31:0] max_pkt_size ;

assign write = (rw == 1'b0);
assign read  = (rw == 1'b1);

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        config_reg <= 32'h0;
    end
    else begin
        if((addr == 8'h0) && (write == 1'b1)) begin
            config_reg <= din;
        end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        max_pkt_size <= 32'h0;
    end
    else begin
        if((addr == 8'h4) && (write == 1'b1)) begin
            max_pkt_size <= din;
        end
    end
end

always @(addr) begin
    case(addr)
        8'h0    : dout = config_reg;
        8'h1    : dout = max_pkt_size;
        default : dout = 32'h0;
    endcase
end

endmodule

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] din   ;
logic        rw    ;
logic [31:0] dout  ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output din  ;
    output rw   ;
    input  dout ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

string name;
rand logic [7:0] addr;
rand logic rw;
rand logic [31:0] din;
logic [31:0] dout = 32'h0;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, din = %0h, rw = %d, dout = %0h", prefix, $realtime, name, addr, din, rw, dout);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
cpu_transaction cpu_tran;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        for(int i=0; i<run_for_n_trans; i++) begin
            cpu_transaction cpu_tran_cpy = new cpu_tran;
            if(!cpu_tran_cpy.randomize()) begin
                $display("Error to randomize cpu_tran_cpy");
            end
            out_box.put(cpu_tran_cpy);
        end
        ->done;
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
//driver and monitor in the same bfm
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
cpu_tran_mbox out_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.out_box = out_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.din  <= cpu_tran.din;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            @(cpu_intf.cb);
            cpu_tran.dout     = cpu_intf.cb.dout;
            cpu_intf.cb.addr <= 8'h0 ;
            cpu_intf.cb.din  <= 32'h0 ;
            cpu_intf.cb.rw   <= 1'b1 ;

            out_box.put(cpu_tran);
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"

program test(cpu_interface.master cpu_intf);

class cpu_transaction_ext extends cpu_transaction;
    constraint addr_range {addr[7:2] inside {[8'h0:8'h1]}; addr[1:0] == 2'h0;}
    //constraint write {rw == 1'b0;}
endclass

event done;
cpu_tran_mbox drv_mbox = new();
cpu_tran_mbox mon_mbox = new();
cpu_generator cpu_gen;
cpu_driver    cpu_drv;
cpu_transaction_ext cpu_tran_ext = new();

initial begin
    cpu_gen = new("CPU Generator", drv_mbox);
    cpu_drv = new("CPU Driver", drv_mbox, mon_mbox, cpu_intf);

    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b1;
    @(cpu_intf.cb);

    cpu_gen.cpu_tran = cpu_tran_ext;
    cpu_gen.run_for_n_trans = 100;
    cpu_gen.start();
    cpu_drv.start();

    @cpu_gen.done;
    repeat(100) @(cpu_intf.cb);
    $finish();
end

initial begin
    cpu_transaction cpu_tran = new();
    forever begin
        mon_mbox.get(cpu_tran);
        cpu_tran.display("Monitor Mbox");
    end
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

dut u_dut (
    .clk   (cpu_intf.clk   ) ,
    .rst_n (cpu_intf.rst_n ) ,
    .addr  (cpu_intf.addr  ) ,
    .din   (cpu_intf.din   ) ,
    .rw    (cpu_intf.rw    ) ,
    .dout  (cpu_intf.dout  )
);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/monitor
RTL = $(RTL_DIR)/dut.v

TB_DIR = /mnt/monitor
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

103) scoreboard
/////////////////////////////////////////////
//dut.v
/////////////////////////////////////////////
`timescale 1ns/1ps

module dut(
    clk   ,
    rst_n ,
    addr  ,
    din   ,
    rw    ,
    dout
);

input         clk   ;
input         rst_n ;
input  [7:0 ] addr  ;
input  [31:0] din   ;
input         rw    ;

output [31:0] dout  ;

wire        clk   ;
wire        rst_n ;
wire [7:0 ] addr  ;
wire [31:0] din   ;
wire        rw    ;

reg  [31:0] dout  ;

wire        write ;
wire        read  ;

reg  [31:0] config_reg ;
reg  [31:0] max_pkt_size ;

assign write = (rw == 1'b0);
assign read  = (rw == 1'b1);

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        config_reg <= 32'h0;
    end
    else begin
        if((addr == 8'h0) && (write == 1'b1)) begin
            config_reg <= din;
        end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        max_pkt_size <= 32'h0;
    end
    else begin
        if((addr == 8'h4) && (write == 1'b1)) begin
            max_pkt_size <= din;
        end
    end
end

always @(*) begin
    case(addr)
        8'h0    : dout = config_reg;
        8'h4    : dout = max_pkt_size;
        default : dout = 32'h0;
    endcase
end

endmodule

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] din   ;
logic        rw    ;
logic [31:0] dout  ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output din  ;
    output rw   ;
    input  dout ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

string name;
rand logic [7:0] addr;
rand logic rw;
rand logic [31:0] din;
logic [31:0] dout = 32'h0;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, din = %0h, rw = %d, dout = %0h", prefix, $realtime, name, addr, din, rw, dout);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
cpu_transaction cpu_tran;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        for(int i=0; i<run_for_n_trans; i++) begin
            cpu_transaction cpu_tran_cpy = new cpu_tran;
            if(!cpu_tran_cpy.randomize()) begin
                $display("Error to randomize cpu_tran_cpy");
            end
            out_box.put(cpu_tran_cpy);
        end
        ->done;
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
cpu_tran_mbox out_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.out_box = out_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.din  <= cpu_tran.din;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            if(cpu_tran.rw == 1'b1) begin
                @(cpu_intf.cb);
                cpu_tran.dout     = cpu_intf.cb.dout;
            end

            out_box.put(cpu_tran);
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_scoreboard.sv
/////////////////////////////////////////////
`ifndef __CPU_SCOREBOARD_SV__
`define __CPU_SCOREBOARD_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_scoreboard;

string name;
cpu_tran_mbox in_box;
cpu_transaction cpu_tran;

logic [31:0] cpu_reg [7:0];
integer error_no = 0;
integer total_no = 0;

extern function new(string name = "CPU Scoreboard", cpu_tran_mbox in_box);
extern task start();
extern task check();
extern function display(string prefix = "CPU Scoreboard Result");

endclass

function cpu_scoreboard::new(string name, cpu_tran_mbox in_box);
    this.name = name;
    this.in_box = in_box;

    for(int i=0; i<128; i++) begin
        cpu_reg[i] = 32'h0;
    end
endfunction

task cpu_scoreboard::start();
    fork
        forever begin
            in_box.get(cpu_tran);
            total_no++;
            check();
        end
    join_none
endtask

task cpu_scoreboard::check();
    string message;
    if(cpu_tran.rw == 1'b0) begin
        cpu_reg[cpu_tran.addr] = cpu_tran.din;
    end
    else if(cpu_tran.rw == 1'b1) begin
        if(cpu_reg[cpu_tran.addr] != cpu_tran.dout) begin
            message = $psprintf("[Error] %t Comparision result is not correct\n", $realtime);
            message = { message, $psprintf("cpu_reg[%d] = %0h, cpu_tran.dout = %0h\n", cpu_tran.addr, cpu_reg[cpu_tran.addr], cpu_tran.dout) };
            $display(message);
            error_no++;
        end
        else begin
            $display("[Note] %t comparison correct", $realtime);
        end
    end
    else begin
        $display("[Error] cpu_tran.rw can only be 0 or 1");
        error_no++;
    end
endtask

function cpu_scoreboard::display(string prefix);
    $display("Total: %d, Error: %d", total_no, error_no);
endfunction

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"
`include "cpu_scoreboard.sv"

program test(cpu_interface.master cpu_intf);

class cpu_transaction_ext extends cpu_transaction;
    constraint addr_range {addr[7:2] inside {[8'h0:8'h1]}; addr[1:0] == 2'h0;}
    //constraint write {rw == 1'b0;}
endclass

event done;
cpu_tran_mbox drv_mbox = new();
cpu_tran_mbox mon_mbox = new();
cpu_generator cpu_gen;
cpu_driver    cpu_drv;
cpu_transaction_ext cpu_tran_ext = new();
cpu_scoreboard cpu_sb;

initial begin
    cpu_gen = new("CPU Generator", drv_mbox);
    cpu_drv = new("CPU Driver", drv_mbox, mon_mbox, cpu_intf);
    cpu_sb  = new("CPU Scoreboard", mon_mbox);

    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b1;
    @(cpu_intf.cb);

    cpu_gen.cpu_tran = cpu_tran_ext;
    cpu_gen.run_for_n_trans = 100;
    cpu_gen.start();
    cpu_drv.start();
    cpu_sb.start();

    @cpu_gen.done;
    repeat(1000) begin
        @(cpu_intf.cb);
        if(cpu_sb.total_no == cpu_gen.run_for_n_trans) begin
            break;
        end
    end
    cpu_sb.display();
    $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

dut u_dut (
    .clk   (cpu_intf.clk   ) ,
    .rst_n (cpu_intf.rst_n ) ,
    .addr  (cpu_intf.addr  ) ,
    .din   (cpu_intf.din   ) ,
    .rw    (cpu_intf.rw    ) ,
    .dout  (cpu_intf.dout  )
);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/scoreboard
RTL = $(RTL_DIR)/dut.v

TB_DIR = /mnt/scoreboard
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

104) env
/////////////////////////////////////////////
//dut.v
/////////////////////////////////////////////
`timescale 1ns/1ps

module dut(
    clk   ,
    rst_n ,
    addr  ,
    din   ,
    rw    ,
    dout
);

input         clk   ;
input         rst_n ;
input  [7:0 ] addr  ;
input  [31:0] din   ;
input         rw    ;

output [31:0] dout  ;

wire        clk   ;
wire        rst_n ;
wire [7:0 ] addr  ;
wire [31:0] din   ;
wire        rw    ;

reg  [31:0] dout  ;

wire        write ;
wire        read  ;

reg  [31:0] config_reg ;
reg  [31:0] max_pkt_size ;

assign write = (rw == 1'b0);
assign read  = (rw == 1'b1);

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        config_reg <= 32'h0;
    end
    else begin
        if((addr == 8'h0) && (write == 1'b1)) begin
            config_reg <= din;
        end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        max_pkt_size <= 32'h0;
    end
    else begin
        if((addr == 8'h4) && (write == 1'b1)) begin
            max_pkt_size <= din;
        end
    end
end

always @(*) begin
    case(addr)
        8'h0    : dout = config_reg;
        8'h4    : dout = max_pkt_size;
        default : dout = 32'h0;
    endcase
end

endmodule

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] din   ;
logic        rw    ;
logic [31:0] dout  ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output din  ;
    output rw   ;
    input  dout ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

string name;
rand logic [7:0] addr;
rand logic rw;
rand logic [31:0] din;
logic [31:0] dout = 32'h0;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, din = %0h, rw = %d, dout = %0h", prefix, $realtime, name, addr, din, rw, dout);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
cpu_transaction cpu_tran;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        begin
            for(int i=0; i<run_for_n_trans; i++) begin
                cpu_transaction cpu_tran_cpy = new cpu_tran;
                if(!cpu_tran_cpy.randomize()) begin
                    $display("Error to randomize cpu_tran_cpy");
                end
                out_box.put(cpu_tran_cpy);
            end
            ->done;
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
cpu_tran_mbox out_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.out_box = out_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.din  <= cpu_tran.din;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            if(cpu_tran.rw == 1'b1) begin
                @(cpu_intf.cb);
                cpu_tran.dout     = cpu_intf.cb.dout;
            end

            out_box.put(cpu_tran);
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_scoreboard.sv
/////////////////////////////////////////////
`ifndef __CPU_SCOREBOARD_SV__
`define __CPU_SCOREBOARD_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_scoreboard;

string name;
cpu_tran_mbox in_box;
cpu_transaction cpu_tran;

logic [31:0] cpu_reg [7:0];
integer error_no = 0;
integer total_no = 0;

extern function new(string name = "CPU Scoreboard", cpu_tran_mbox in_box);
extern task start();
extern task check();
extern function display(string prefix = "CPU Scoreboard Result");

endclass

function cpu_scoreboard::new(string name, cpu_tran_mbox in_box);
    this.name = name;
    this.in_box = in_box;

    for(int i=0; i<128; i++) begin
        cpu_reg[i] = 32'h0;
    end
endfunction

task cpu_scoreboard::start();
    fork
        forever begin
            in_box.get(cpu_tran);
            total_no++;
            check();
        end
    join_none
endtask

task cpu_scoreboard::check();
    string message;
    if(cpu_tran.rw == 1'b0) begin
        cpu_reg[cpu_tran.addr] = cpu_tran.din;
    end
    else if(cpu_tran.rw == 1'b1) begin
        if(cpu_reg[cpu_tran.addr] != cpu_tran.dout) begin
            message = $psprintf("[Error] %t Comparision result is not correct\n", $realtime);
            message = { message, $psprintf("cpu_reg[%d] = %0h, cpu_tran.dout = %0h\n", cpu_tran.addr, cpu_reg[cpu_tran.addr], cpu_tran.dout) };
            $display(message);
            error_no++;
        end
        else begin
            $display("[Note] %t comparison correct", $realtime);
        end
    end
    else begin
        $display("[Error] cpu_tran.rw can only be 0 or 1");
        error_no++;
    end
endtask

function cpu_scoreboard::display(string prefix);
    $display("Total: %d, Error: %d", total_no, error_no);
endfunction

`endif

/////////////////////////////////////////////
//cpu_env.sv
/////////////////////////////////////////////
`ifndef __CPU_ENV_SV__
`define __CPU_ENV_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"
`include "cpu_scoreboard.sv"

class cpu_env;

cpu_tran_mbox  drv_mbox = new();
cpu_tran_mbox  mon_mbox = new();
cpu_generator  cpu_gen;
cpu_driver     cpu_drv;
cpu_scoreboard cpu_sb;

virtual cpu_interface.master cpu_intf;

extern function new(virtual cpu_interface.master cpu_intf);
extern function configure();
extern task reset();
extern task start();

endclass

function cpu_env::new(virtual cpu_interface.master cpu_intf);
    this.cpu_intf = cpu_intf;
    cpu_gen = new("CPU Generator", drv_mbox);
    cpu_drv = new("CPU Driver", drv_mbox, mon_mbox, cpu_intf);
    cpu_sb  = new("CPU Scoreboard", mon_mbox);
endfunction

function cpu_env::configure();
endfunction

task cpu_env::reset();
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b1;
    @(cpu_intf.cb);
endtask

task cpu_env::start();
    cpu_gen.start();
    cpu_drv.start();
    cpu_sb.start();
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_env.sv"

program test(cpu_interface.master cpu_intf);

class cpu_transaction_ext extends cpu_transaction;
    constraint addr_range {addr[7:2] inside {[8'h0:8'h1]}; addr[1:0] == 2'h0;}
    //constraint write {rw == 1'b0;}
endclass

cpu_transaction_ext cpu_tran_ext = new();
cpu_env cpu_e;

initial begin
    cpu_e = new(cpu_intf);
    cpu_e.configure();

    cpu_e.cpu_gen.cpu_tran = cpu_tran_ext;
    cpu_e.cpu_gen.run_for_n_trans = 100;

    cpu_e.reset();
    cpu_e.start();

    @cpu_e.cpu_gen.done;
    repeat(1000) begin
        @(cpu_intf.cb);
        if(cpu_e.cpu_sb.total_no == cpu_e.cpu_gen.run_for_n_trans) begin
            break;
        end
    end
    cpu_e.cpu_sb.display();
    $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

dut u_dut (
    .clk   (cpu_intf.clk   ) ,
    .rst_n (cpu_intf.rst_n ) ,
    .addr  (cpu_intf.addr  ) ,
    .din   (cpu_intf.din   ) ,
    .rw    (cpu_intf.rw    ) ,
    .dout  (cpu_intf.dout  )
);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/env
RTL = $(RTL_DIR)/dut.v

TB_DIR = /mnt/env
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

110) driver and monitor are in 2 different class (bfm)
link: http://scott2595.blogspot.com/2014/08/an-example-of-systemverilog-tb.html

111) TB env with 2 TB envs
linke: http://scott2595.blogspot.com/2014/10/an-example-of-sv-tb-with-callback.html

No comments:

Post a Comment